home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Toolbox / Visual Basic Toolbox (P.I.E.)(1996).ISO / toolkit / vbof_v11 / vbofcoll.cls < prev    next >
Text File  |  1996-03-03  |  136KB  |  4,280 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "VBOFCollection"
  6. Attribute VB_Creatable = True
  7. Attribute VB_Exposed = True
  8. Option Explicit
  9.  
  10. ' (c) Copyright 1995 Ken Fitzpatrick
  11. '     All Rights Reserved
  12. '     Cannot be distributed or sold without permission
  13. '
  14. ' VBObjectFrameworkCollection is a database-aware
  15. '     Collection class supplemental for Microsoft
  16. '     Visual Basic 4.0.
  17. ' This version of VBOFCollection is intended only
  18. '     to be used in conjunction with the following
  19. '     Class Modules:
  20. '       VBOFObjectManager (required)
  21. '       VBOFEventManager  (optional, see comments in VBOFObjectManager for details)
  22. '       VBOFEventObject   (optional, see comments in VBOFObjectManager for details)
  23. ' and cannot be used in a "stand-alone" mode, that
  24. '   is, without the support of the above required
  25. '   Class Modules nor can this version be used as
  26. '   the application program's initial point of
  27. '   contact with the VBObjectFramework (the required
  28. '   initial point of contace must be the
  29. '   VBOFObjectManager)
  30. '
  31.  
  32. Public ObjectID As Long
  33.  
  34. Private pvtCollection As Collection
  35.  
  36. Private pvtVBOFObjectManager As VBOFObjectManager
  37. Private pvtVBOFListBoxWrapper As VBOFListBoxWrapper
  38.  
  39. Private pvtSample As Object
  40. Private pvtParent As Object
  41. Private pvtMostRecentlyAddedObject As Object
  42. Private pvtSampleTableName As String
  43. Private pvtSampleType As String
  44. Private pvtParentTableName As String
  45. Private pvtParentType As String
  46. Private pvtListBox As Variant
  47. Private pvtDBGrid As Variant
  48. Private pvtNewIndex As Long
  49.  
  50. Private pvtDatabase As Database
  51. Private pvtRecordSet As RecordSet
  52. Private pvtSQLStatement As String
  53. Private pvtWhereClause As String
  54. Private pvtOrderByClause As String
  55. Private pvtCollectionEmulationMode As Boolean
  56. Private pvtRecordSetProvidedByUser As Boolean
  57. Private pvtSQLStatementProvidedByUser As Boolean
  58. Private pvtDBHasBeenReferenced As Boolean
  59. Private pvtANSISQL As Boolean
  60. Private pvtSwapIfEqualSortOrder As Boolean
  61. Private pvtODBCPassThrough As Long
  62. Private pvtDBGridBookmarkArray() As Variant
  63. Private pvtDBGridBookmarkArrayAvailable As Boolean
  64. Private pvtAutoDeleteOrphans As Boolean
  65. Private pvtAutoDeleteOrphansHasBeenInitialized As Boolean
  66. Private RC As Long
  67.  
  68. Private Const pvtReceiverDoesNotSupportThisMethod = 438
  69.  
  70. Public Property Let AutoDeleteOrphans(aBoolean As Boolean)
  71.     pvtAutoDeleteOrphans = aBoolean
  72.     pvtAutoDeleteOrphansHasBeenInitialized = True
  73. End Property
  74.  
  75. Public Property Get AutoDeleteOrphans() As Boolean
  76.     If pvtAutoDeleteOrphansHasBeenInitialized Then
  77.         AutoDeleteOrphans = _
  78.             pvtAutoDeleteOrphans
  79.     Else
  80.         AutoDeleteOrphans = _
  81.             pvtVBOFObjectManager.AutoDeleteOrphans
  82.     End If
  83. End Property
  84.  
  85.  
  86.  
  87. Private Sub pvtDBGridBookmarkArraySwap(I, J)
  88.     
  89.     Dim tempBookmark As Variant
  90.     Dim tempObjectID As Long
  91.     
  92. '    tempBookmark = _
  93. '        CStr(pvtDBGridBookmarkArray(1, I))
  94.     tempObjectID = _
  95.         pvtDBGridBookmarkArray(2, I)
  96.     
  97. '    pvtDBGridBookmarkArray(1, I) = _
  98. '        pvtDBGridBookmarkArray(1, J)
  99.     pvtDBGridBookmarkArray(2, I) = _
  100.         pvtDBGridBookmarkArray(2, J)
  101.  
  102. '    pvtDBGridBookmarkArray(1, J) = _
  103. '        tempBookmark
  104.     pvtDBGridBookmarkArray(2, J) = _
  105.         tempObjectID
  106.  
  107. End Sub
  108.  
  109. Public Function pvtEmptyCollection(Optional NoDelete As Variant, Optional CleanUpMode As Variant) As Boolean
  110. ' Empties this the VBOFCollection of all its Objects.
  111. '
  112. ' Note: if a DataSource is supporting the Collection
  113. '   then the VBOF automatic containment links to
  114. '   the contained objects are also severed
  115.  
  116.     On Local Error Resume Next
  117.     
  118.     pvtEmptyCollection = _
  119.         ObjectManager. _
  120.             EmptyCollection( _
  121.                 Collection:=Me, _
  122.                 NoDelete:=NoDelete, _
  123.                 CleanUpMode:=CleanUpMode)
  124.  
  125. End Function
  126.  
  127. Public Function pvtCloseRecordSet() As Long
  128. ' Closes the current RecordSet.  This might be
  129. '   useful if using the VBOFCollection to
  130. '   populate a ListBox or Grid.
  131. ' Returns the VB Err code associated with closing
  132. '   the RecordSet.
  133. ' Note: this method should be used with caution.
  134.  
  135.     On Local Error Resume Next
  136.  
  137.     pvtRecordSet.Close
  138.     
  139.     pvtCloseRecordSet = Err
  140. End Function
  141.  
  142.  
  143. Public Function PopulateCollection( _
  144.     Optional Database As Variant, _
  145.     Optional RecordSet As Variant, _
  146.     Optional Sample As Variant, _
  147.     Optional Parent As Variant, _
  148.     Optional WhereClause As Variant, _
  149.     Optional SQL As Variant, _
  150.     Optional OrderByClause As Variant, _
  151.     Optional ODBCPassThrough As Variant, _
  152.     Optional ANSISQL As Variant) As VBOFCollection
  153. ' Returns a populated VBOFCollection.
  154. '   Serves a purpose of simplification for the
  155. '   user.  This method gives the user a single
  156. '   method to invoke for instantiating the
  157. '   VBOFCollection, regardless of whether
  158. '   the "pvtPopulateFromDatabase" method or
  159. '   the "pvtPopulateFromRecordSet" method is
  160. '   actually used.
  161. '
  162. ' Either Database:= or RecordSet:= must be provided.
  163. '   For RecordSet:= support, the caller must have
  164. '       independently created the RecordSet object.
  165. '   Otherwise, the Database:= parameter should be
  166. '       specified and VBOFCollection will create
  167. '       the underlying RecordSet automatically
  168. '
  169. ' Parameter Description:
  170. '   see VBOFObjectManager.ManageCollection
  171.     
  172.     If Not IsMissing(RecordSet) Then
  173.         Set PopulateCollection = _
  174.             pvtPopulateFromRecordSet( _
  175.                 RecordSet:=RecordSet, _
  176.                 Parent:=Parent, _
  177.                 Sample:=Sample, _
  178.                 SQL:=SQL, _
  179.                 ANSISQL:=ANSISQL, _
  180.                 WhereClause:=WhereClause, _
  181.                 OrderByClause:=OrderByClause, _
  182.                 ODBCPassThrough:=ODBCPassThrough)
  183.     ElseIf Not pvtDatabase Is Nothing Then
  184.         Set PopulateCollection = _
  185.             pvtPopulateFromDatabase( _
  186.                 Database:=Database, _
  187.                 Parent:=Parent, _
  188.                 Sample:=Sample, _
  189.                 SQL:=SQL, _
  190.                 ANSISQL:=ANSISQL, _
  191.                 WhereClause:=WhereClause, _
  192.                 OrderByClause:=OrderByClause, _
  193.                 ODBCPassThrough:=ODBCPassThrough)
  194.     Else
  195.         pvtCollectionEmulationMode = True
  196.         Set PopulateCollection = Me
  197.     End If
  198.  
  199. End Function
  200.  
  201. Public Function pvtDataValidate(Optional DataControl As Variant, Optional Action As Variant, Optional Save As Variant, Optional Sample As Variant, Optional Parent As Variant) As Variant
  202.  
  203.     Dim tempObject As Object
  204.     
  205.     On Local Error Resume Next
  206.  
  207. ' bullet-proofing
  208.     If IsMissing(Action) Then
  209.         Set pvtDataValidate = Nothing
  210.         Exit Function
  211.     End If
  212.     If IsMissing(Save) Then
  213.         Set pvtDataValidate = Nothing
  214.         Exit Function
  215.     End If
  216.         
  217.     If Not pvtSetSample( _
  218.             Sample:=Sample, _
  219.             MethodName:="pvtDataValidate") Then
  220.         Set pvtDataValidate = Nothing
  221.         GoTo pvtDataValidate_Exit
  222.     End If
  223.     If Not pvtSetParent( _
  224.             Parent:=Parent, _
  225.             MethodName:="pvtDataValidate") Then
  226.         Set pvtDataValidate = Nothing
  227.         Exit Function
  228.     End If
  229.  
  230. ' process according to Action
  231.     Select Case Action
  232.  
  233. ' process Action=AddNew
  234.         Case vbDataActionAddNew
  235.             
  236. ' instantiate a new object
  237.             Set tempObject = _
  238.                 ObjectManager. _
  239.                     pvtInstantiateNewObjectFromSample _
  240.                         (Sample:=pvtSample)
  241.             If tempObject Is Nothing Then
  242.                 Set pvtDataValidate = Nothing
  243.                 Exit Function
  244.             End If
  245.  
  246. ' have the new instantiated object copy populate
  247. '   itself from this RecordSet row
  248.             Set tempObject = _
  249.                 ObjectManager. _
  250.                     pvtObjectInitializeFromRecordSet( _
  251.                         Object:=tempObject, _
  252.                         RecordSet:=pvtRecordSet)
  253.             If tempObject Is Nothing Then
  254.                 Set pvtDataValidate = Nothing
  255.                 Exit Function
  256.             End If
  257.             
  258. ' add the new object to Me.RecordSet
  259.             Set tempObject = _
  260.                 Me.Add( _
  261.                     Item:=tempObject)
  262.                     
  263.             Set DataControl.RecordSet = _
  264.                 pvtRecordSet
  265.  
  266. ' process Action=Update
  267.         Case vbDataActionUpdate
  268.             
  269. ' get the object at the RecordSet row
  270.             Set tempObject = _
  271.                 pvtRecordSetMoveToRecordNumber _
  272.                     (pvtRecordSet.AbsolutePosition)
  273.  
  274. ' have the new instantiated object copy populate
  275. '   itself from this RecordSet row
  276.             Set tempObject = _
  277.                 ObjectManager. _
  278.                     pvtObjectInitializeFromRecordSet( _
  279.                         Object:=tempObject, _
  280.                         RecordSet:=pvtRecordSet)
  281.             If tempObject Is Nothing Then
  282.                 Set pvtDataValidate = Nothing
  283.                 Exit Function
  284.             End If
  285.         
  286. ' update the object in the Collection
  287.             Replace _
  288.                Item:=tempObject, _
  289.                ReplaceWith:=tempObject
  290.  
  291. ' process Action=Delete
  292.         Case vbDataActionDelete
  293.             
  294. ' get the object at the RecordSet row
  295.             Set tempObject = _
  296.                 pvtRecordSetMoveToRecordNumber _
  297.                     (pvtRecordSet.AbsolutePosition)
  298.  
  299. ' remove the object from the Collection
  300.             Remove _
  301.                 Item:=tempObject, _
  302.                 NoDelete:=True
  303.         
  304.         End Select
  305.  
  306. pvtDataValidate_Exit:
  307.     Set pvtDataValidate = tempObject
  308.     Set tempObject = Nothing
  309. End Function
  310.  
  311.  
  312. Private Function pvtIsAnOrphan(Optional Item As Variant) As Boolean
  313. ' Determines whether or not the Item is an Orphan
  314.  
  315.     Dim tempCountOfParentLinksToItem As Long
  316.  
  317. ' count the number of Parent objects which currently
  318. '   reference Item
  319.     tempCountOfParentLinksToItem = _
  320.         pvtCountOfParentLinksToItem( _
  321.            Child:=Item, _
  322.            Parent:=pvtParent)
  323.  
  324.     If tempCountOfParentLinksToItem > 0 Then
  325.         pvtIsAnOrphan = False
  326.     Else
  327.         pvtIsAnOrphan = True
  328.     End If
  329. End Function
  330.  
  331.  
  332. Public Property Get ObjectDataSource() As String
  333. Attribute ObjectDataSource.VB_Description = "Private"
  334.     ObjectDataSource = _
  335.         "VBObjectFrameworkObjectLinks"
  336. End Property
  337.  
  338. Private Function pvtAddUniqueItemToCollection(Optional Item As Variant, Optional Parent As Variant, Optional Collection As Variant) As Variant
  339. ' Add the Item to the Collection, if it is unique.
  340. ' Return the object which is actually added to
  341. '   the Collection
  342.         
  343.     Dim tempObject As Object
  344.         
  345.     On Local Error Resume Next
  346.     
  347. ' bullet-proofing
  348.     If IsMissing(Item) _
  349.     Or IsMissing(Parent) _
  350.     Or IsMissing(Collection) Then
  351.         Set pvtAddUniqueItemToCollection = Nothing
  352.         Exit Function
  353.     End If
  354.         
  355. ' verify that the object is unique across
  356. '   the known system objects
  357.     Set tempObject = _
  358.         pvtVBOFObjectManager. _
  359.             pvtAddUniqueObject( _
  360.                 Object:=Item, _
  361.                 Parent:=Parent)
  362.  
  363. ' add the object to the collection
  364.     Collection.Add _
  365.         Item:=tempObject, _
  366.         Key:=CStr(tempObject.ObjectID)
  367.  
  368. ' add the reference to the pvtDBGridBookmarkArray
  369.     pvtAddItemToDBGridArray _
  370.         Item:=tempObject, _
  371.         Collection:=Collection
  372.  
  373. ' return the unique object
  374.     Set pvtAddUniqueItemToCollection = _
  375.         tempObject
  376. End Function
  377.  
  378. Private Function pvtCollectionIndexForWhereClause(Optional WhereClause As Variant, Optional FindFirst As Variant, Optional FindNext As Variant, Optional FindLast As Variant, Optional FindPrevious As Variant) As Variant
  379. ' Returns the next object in the collection which
  380. '   meets the criteria of the WhereClause.
  381. ' Note: processing is based on the RecordSet, thus
  382. '   positioning is relative to the positioning of
  383. '   the underlying RecordSet.  See also methods
  384. '   "RecordSet" and "pvtRecordSetMoveFirst"
  385. ' Parameters:
  386. '   WhereClause - a search string which can be
  387. '       appended to the RecordSet.FindNext method
  388. '   FindFirst - a boolean which determines whether
  389. '       the FindNext or FindFirst method should be
  390. '       used
  391.  
  392.     Dim tempFindFirst As Boolean
  393.     Dim tempFindNext As Boolean
  394.     Dim tempFindLast As Boolean
  395.     Dim tempFindPrevious As Boolean
  396.     Dim tempObjectID As Long
  397.     Dim I As Long
  398.     Dim tempObject As Variant
  399.  
  400.     On Local Error Resume Next
  401.     
  402.     tempFindNext = True
  403.  
  404. ' bullet-proofing
  405.     If pvtRecordSet Is Nothing Then
  406.         pvtCollectionIndexForWhereClause = -1
  407.         GoTo pvtCollectionIndexForWhereClause_Exit
  408.     End If
  409.     If pvtCollection.Count <= 0 Then
  410.         pvtCollectionIndexForWhereClause = -1
  411.         GoTo pvtCollectionIndexForWhereClause_Exit
  412.     End If
  413.     If pvtCollection(1).ObjectDataSource = "" Or Err = 438 Then
  414.         pvtCollectionIndexForWhereClause = -1
  415.         GoTo pvtCollectionIndexForWhereClause_Exit
  416.     End If
  417.     
  418. ' set FindFirst
  419.     tempFindFirst = False
  420.     If Not IsMissing(FindFirst) Then
  421.         tempFindFirst = FindFirst
  422.     End If
  423.     
  424. ' set FindLast
  425.     tempFindLast = False
  426.     If Not IsMissing(FindLast) Then
  427.         tempFindLast = FindLast
  428.     End If
  429.     
  430. ' set FindPrevious
  431.     tempFindPrevious = False
  432.     If Not IsMissing(FindPrevious) Then
  433.         tempFindPrevious = FindPrevious
  434.     End If
  435.     
  436. ' search for the next qualifying row in the RecordSet
  437.     If tempFindPrevious Then
  438.         pvtRecordSet.FindPrevious WhereClause
  439.     ElseIf tempFindLast Then
  440.         pvtRecordSet.FindLast WhereClause
  441.     ElseIf tempFindFirst Then
  442.         pvtRecordSet.FindFirst WhereClause
  443.     Else
  444.         pvtRecordSet.FindNext WhereClause
  445.     End If
  446.     
  447.     If pvtRecordSet.NoMatch Then
  448.         pvtCollectionIndexForWhereClause = -1
  449.         GoTo pvtCollectionIndexForWhereClause_Exit
  450.     End If
  451.  
  452. ' save the ObjectID of the found record
  453.     tempObjectID = pvtRecordSet("ObjectID")
  454.  
  455. ' search for the corresponding object
  456.     I = 1
  457.     For Each tempObject In pvtCollection
  458.         If tempObject.ObjectID = tempObjectID Then
  459.             pvtCollectionIndexForWhereClause = I
  460.             GoTo pvtCollectionIndexForWhereClause_Exit
  461.         End If
  462.         
  463.         I = I + 1
  464.     Next tempObject
  465.  
  466.     pvtCollectionIndexForWhereClause = -1
  467.  
  468. pvtCollectionIndexForWhereClause_Exit:
  469.     Set tempObject = Nothing
  470.     
  471. End Function
  472.  
  473.  
  474. Public Function pvtDBGridUnboundReadData(Optional DBGrid As Variant, Optional RowBuf As Variant, Optional StartLocation As Variant, Optional ReadPriorRows As Variant) As Long
  475. ' Populates the DBGrid with one row of information
  476. '   for each object in this VBOFCollection.
  477. ' Returns the number of rows added to the DBGrid
  478. ' Note:  the referenced objects must contain the
  479. '   method 'ObjectDBGridValue', which must populate
  480. '   and return the RowBuffer object
  481. '   (for more information, find "RowBuffer" in the
  482. '   online VB Help.)
  483. '
  484. ' Note:  this method should be coded in the
  485. '   DBGrid's UnboundReadData Event Procedure,
  486. '   as follows:
  487. '
  488. '   Private Sub DBGrid1_UnboundReadData(ByVal RowBuf As RowBuffer, StartLocation As Variant, ByVal ReadPriorRows As Boolean)
  489. '       MyVBOFCollection.pvtDBGridUnboundReadData _
  490. '           DBGrid:=DBGrid1, _
  491. '           RowBuf:=RowBuf, _
  492. '           StartLocation:=StartLocation, _
  493. '           ReadPriorRows:=ReadPriorRows
  494. '   End Sub
  495.  
  496.     Dim tempObject As Object
  497.     Dim tempIncrement As Long
  498.     Dim tempCurrentRowIndex As Long
  499.     Dim tempRowIndex As Long
  500.     Dim tempColumnIndex As Long
  501.     Dim tempRowsFetched As Long
  502.     Dim tempBookmark As Variant
  503.     
  504.     On Local Error Resume Next
  505.     
  506. ' bullet-proofing
  507.     If IsMissing(DBGrid) Or IsMissing(RowBuf) Then
  508.         If pvtDBGrid Is Nothing Then
  509.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridUnboundReadData' method for this object because the 'DBGrid' or 'RowBuf' parameter is missing."
  510.             pvtDBGridUnboundReadData = False
  511.             GoTo pvtDBGridUnboundReadData_Exit
  512.         End If
  513.     Else
  514.         Set pvtDBGrid = DBGrid
  515.     End If
  516.     
  517.     If ReadPriorRows Then
  518.         tempIncrement = -1
  519.     Else
  520.         tempIncrement = 1
  521.     End If
  522.  
  523.     tempBookmark = StartLocation
  524.  
  525. ' process the row
  526.     tempRowsFetched = 0
  527.     For tempRowIndex = 0 To RowBuf.RowCount - 1
  528.         
  529.         tempBookmark = _
  530.             pvtDBGridGetRelativeBookmark( _
  531.                 tempBookmark, _
  532.                 tempIncrement, _
  533.                 pvtCollection.Count)
  534.  
  535.         If IsNull(tempBookmark) Then
  536.             Exit For
  537.         End If
  538.  
  539. ' reference the object associated with the
  540. '   current row, indexed by relative position
  541. '   within the pvtCollection
  542.         Set tempObject = _
  543.             pvtCollection.Item _
  544.                 (CLng(tempBookmark) + 1)
  545.  
  546. ' have the object complete the RowBuf
  547. '   with its own Property values
  548.         tempObject.ObjectDBGridUnboundReadData _
  549.             DBGrid:=pvtDBGrid, _
  550.             RowBuf:=RowBuf, _
  551.             RowNumber:=tempCurrentRowIndex
  552.  
  553. ' assign the Bookmark to the row, as returned above.
  554. '   Internally, the CollectionIndex(Object) is used
  555.         RowBuf.Bookmark(tempRowIndex) = _
  556.             tempBookmark
  557.             
  558.         tempCurrentRowIndex = tempCurrentRowIndex + tempIncrement
  559.         tempRowsFetched = tempRowsFetched + 1
  560.         
  561.     Next tempRowIndex
  562.  
  563. pvtDBGridUnboundReadData_Exit:
  564.     Set tempObject = Nothing
  565.     RowBuf.RowCount = tempRowsFetched
  566.     pvtDBGridUnboundReadData = tempRowsFetched
  567. End Function
  568.  
  569. Public Function pvtDBGridUnboundAddData(Optional DBGrid As Variant, Optional RowBuf As Variant, Optional NewRowBookmark As Variant, Optional Sample As Variant, Optional Parent As Variant) As Variant
  570. ' Processes the UnboundAddData event of the DBGrid.
  571. '   Automatically instantiates a new object,
  572. '   populates it, adds it to the VBOFCollection
  573. '   and returns the VBOFCollection to the
  574. '   application.
  575. '
  576. ' Parameters:
  577. '   DBGrid:= identifies the DBGrid
  578. '   RowBuf:= is the same RowBuf parameter found
  579. '       in the application's UnboundAddData event
  580. '       handler
  581. '   NewRowBookmark:= is the same NewRowBookmark
  582. '       parameter found in the application's
  583. '       UnboundAddData event handler
  584. '   Sample:= (Optional) identifies the class
  585. '       type to instantiate with the new data.
  586. '       If a previous VBOFCollection method had
  587. '       already established a Sample:=, this
  588. '       parameter can be eliminated
  589. '   Parent:= (Optional) identifies the object
  590. '       which is the parent ("container") object of
  591. '       the objects in this collection.
  592. '       If a previous VBOFCollection method had
  593. '       already established a Parent:=, this
  594. '       parameter can be eliminated
  595. '
  596. ' Note:  this method should be coded as follows:
  597. '   Private Sub DBGrid1_UnboundAddData(ByVal RowBuf As RowBuffer, NewRowBookmark As Variant)
  598. '       MyVBOFCollection.pvtDBGridUnboundAddData _
  599. '           DBGrid:=DBGrid1, _
  600. '           RowBuf:=RowBuf, _
  601. '           NewRowBookmark:=NewRowBookmark
  602. '
  603. ' or,
  604. '       Dim tempSample as New MyClass
  605. '       MyVBOFCollection.pvtDBGridUnboundAddData _
  606. '           DBGrid:=DBGrid1, _
  607. '           RowBuf:=RowBuf, _
  608. '           NewRowBookmark:=NewRowBookmark, _
  609. '           Sample:=tempSample
  610. '   End Sub
  611.  
  612.     Dim tempNewObject As Object
  613.     
  614.     On Local Error Resume Next
  615.     
  616. ' bullet-proofing
  617.     If IsMissing(DBGrid) _
  618.     Or IsMissing(RowBuf) _
  619.     Or IsMissing(NewRowBookmark) Then
  620.         If pvtDBGrid Is Nothing Then
  621.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridUnboundAddData' method for this object because the 'DBGrid', 'RowBuf' or 'NewRowBookmark' parameter is missing."
  622.             Set pvtDBGridUnboundAddData = Nothing
  623.             GoTo pvtDBGridUnboundAddData_Exit
  624.         End If
  625.     Else
  626.         Set pvtDBGrid = DBGrid
  627.     End If
  628.     If Not pvtSetSample( _
  629.             Sample:=Sample, _
  630.             MethodName:="pvtDBGridUnboundAddData") Then
  631.         Set pvtDBGridUnboundAddData = Nothing
  632.         GoTo pvtDBGridUnboundAddData_Exit
  633.     End If
  634.     If Not pvtSetParent( _
  635.             Parent:=Parent, _
  636.             MethodName:="pvtDBGridUnboundAddData") Then
  637.         Set pvtDBGridUnboundAddData = Nothing
  638.         GoTo pvtDBGridUnboundAddData_Exit
  639.     End If
  640.  
  641. ' instantiate the new object
  642.     Set tempNewObject = _
  643.         ObjectManager. _
  644.             pvtInstantiateNewObjectFromSample _
  645.                 (Sample:=pvtSample)
  646.     If tempNewObject Is Nothing Then
  647.         GoTo pvtDBGridUnboundAddData_Exit
  648.     End If
  649.  
  650. ' have the object populate the object from
  651. '   the new row
  652.     If tempNewObject. _
  653.         ObjectDBGridUnboundAddData( _
  654.             DBGrid:=pvtDBGrid, _
  655.             RowBuf:=RowBuf, _
  656.             NewRowBookmark:=NewRowBookmark) Then
  657.         
  658. ' add the object to the collection and Database,
  659. '   if applicable
  660.         Add _
  661.             Item:=tempNewObject, _
  662.             After:=pvtCollection.Count
  663.     End If
  664.  
  665. pvtDBGridUnboundAddData_Exit:
  666.     Set tempNewObject = Nothing
  667.     Set pvtDBGridUnboundAddData = Me
  668. End Function
  669.  
  670. Public Function pvtDBGridUnboundWriteData(Optional DBGrid As Variant, Optional RowBuf As Variant, Optional WriteLocation As Variant) As Variant
  671. ' Processes the UnboundWriteData event of the DBGrid.
  672. '
  673. ' Parameters:
  674. '   DBGrid:= identifies the DBGrid
  675. '   RowBuf:= is the same RowBuf parameter found
  676. '       in the application's UnboundWriteData event
  677. '       handler
  678. '   WriteLocation:= is the same WriteLocation
  679. '       parameter found in the application's
  680. '       UnboundWriteData event handler
  681. '
  682. ' Note:  this method should be coded as follows:
  683. '   Private Sub DBGrid1_UnboundWriteData(Optional RowBuf As Variant, Optional WriteLocation As Variant)
  684. '       MyVBOFCollection.pvtDBGridUnboundWriteData _
  685. '           DBGrid:=DBGrid1, _
  686. '           RowBuf:=RowBuf, _
  687. '           WriteLocation:=WriteLocation
  688. '   End Sub
  689.  
  690.     Dim tempObjectID As Long
  691.     Dim tempObject As Object
  692.     
  693.     On Local Error Resume Next
  694.     
  695. ' bullet-proofing
  696.     If IsMissing(RowBuf) Then
  697.         pvtErrorMessage TypeName(Me) & " cannot process the '.UnboundWriteData' method for this object because the 'RowBuf:=' parameter is missing."
  698.         Set pvtDBGridUnboundWriteData = Nothing
  699.         GoTo pvtDBGridUnboundWriteData_Exit
  700.     End If
  701.     If IsMissing(WriteLocation) Then
  702.         pvtErrorMessage TypeName(Me) & " cannot process the '.UnboundWriteData' method for this object because the 'WriteLocation:=' parameter is missing."
  703.         Set pvtDBGridUnboundWriteData = Nothing
  704.         GoTo pvtDBGridUnboundWriteData_Exit
  705.     End If
  706.     If IsMissing(DBGrid) Then
  707.         If pvtDBGrid Is Nothing Then
  708.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridUnboundAddData' method for this object because the 'DBGrid' parameter is missing."
  709.             Set pvtDBGridUnboundWriteData = Nothing
  710.             GoTo pvtDBGridUnboundWriteData_Exit
  711.         End If
  712.     Else
  713.         Set pvtDBGrid = DBGrid
  714.     End If
  715.  
  716. ' position to the correct object
  717.     Set tempObject = _
  718.         pvtCollection.Item _
  719.             (CollectionIndex _
  720.                 (Key:=pvtDBGridObjectIDAtBookmark _
  721.                     (WriteLocation)))
  722.  
  723.     If tempObject Is Nothing Then
  724.         Set pvtDBGridUnboundWriteData = Nothing
  725.         GoTo pvtDBGridUnboundWriteData_Exit
  726.     End If
  727.  
  728. ' have the object populate the object from
  729. '   the DBGrid row
  730.     tempObject. _
  731.         ObjectDBGridUnboundAddData _
  732.             DBGrid:=pvtDBGrid, _
  733.             RowBuf:=RowBuf, _
  734.             NewRowBookmark:=WriteLocation
  735.     If Err = pvtReceiverDoesNotSupportThisMethod Then
  736.         pvtErrorMessage "Class Module '" & TypeName(tempObject) & "' does not support the method 'ObjectDBGridUnboundAddData'." & vbCrLf & "Object cannot be supported by " & TypeName(Me) & " without this method."
  737.         GoTo pvtDBGridUnboundWriteData_Exit
  738.     End If
  739.         
  740. ' update the object in the Collection
  741.      Replace _
  742.         Item:=tempObject, _
  743.         ReplaceWith:=tempObject
  744.  
  745. pvtDBGridUnboundWriteData_Exit:
  746.     Set tempObject = Nothing
  747.     Set pvtDBGridUnboundWriteData = Me
  748. End Function
  749.  
  750. Public Function pvtDBGridUnboundDeleteRow(Optional DBGrid As Variant, Optional Bookmark As Variant) As Variant
  751. ' Processes the UnboundDeleteRow event of the
  752. '   DBGrid.
  753. '
  754. ' Parameters:
  755. '   DBGrid:= identifies the DBGrid
  756. '   Bookmark:= is the same Bookmark parameter found
  757. '       in the application's UnboundDeleteRow event
  758. '       handler
  759. '
  760. ' Note:  this method should be coded as follows:
  761. '   Private Sub DBGrid1_UnboundDeleteRow(Optional Bookmark As Variant)
  762. '       MyVBOFCollection.UnboundDeleteRow _
  763. '           DBGrid:=DBGrid1, _
  764. '           Bookmark:=Bookmark
  765. '   End Sub
  766.  
  767.     Dim tempObjectID As Long
  768.     Dim tempObject As Object
  769.     
  770.     On Local Error Resume Next
  771.     
  772. ' bullet-proofing
  773.     If IsMissing(Bookmark) Then
  774.         pvtErrorMessage TypeName(Me) & " cannot process the '.UnboundDeleteRow' method for this object because the 'Bookmark:=' parameter is missing."
  775.         Set pvtDBGridUnboundDeleteRow = Nothing
  776.         GoTo pvtDBGridUnboundDeleteRow_Exit
  777.     End If
  778.     If IsMissing(DBGrid) Then
  779.         If pvtDBGrid Is Nothing Then
  780.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridUnboundAddData' method for this object because the 'DBGrid' parameter is missing."
  781.             Set pvtDBGridUnboundDeleteRow = Nothing
  782.             GoTo pvtDBGridUnboundDeleteRow_Exit
  783.         End If
  784.     Else
  785.         Set pvtDBGrid = DBGrid
  786.     End If
  787.  
  788. ' position to the correct object
  789.     Set tempObject = _
  790.         pvtCollection.Item _
  791.             (CollectionIndex _
  792.                 (Key:=pvtDBGridObjectIDAtBookmark _
  793.                     (Bookmark)))
  794.  
  795.     If tempObject Is Nothing Then
  796.         Set pvtDBGridUnboundDeleteRow = Nothing
  797.         GoTo pvtDBGridUnboundDeleteRow_Exit
  798.     End If
  799.  
  800. ' remove the object from the Collection
  801.     Remove _
  802.         Item:=tempObject, _
  803.         NoDelete:=True
  804.  
  805. pvtDBGridUnboundDeleteRow_Exit:
  806.     Set tempObject = Nothing
  807.     Set pvtDBGridUnboundWriteData = Me
  808. End Function
  809.  
  810. Public Function pvtDBGridSetNumberOfRows(Optional DBGrid As Variant) As Boolean
  811. ' Informs the DBGrid of the number of rows that
  812. '   are to be added
  813. ' Note:  the referenced objects must contain the
  814. '   method 'ObjectDBGridValue', which must populate
  815. '   and return the RowBuffer object
  816. '   (for more information, find "RowBuffer" in the
  817. '   online VB Help.)
  818. '
  819. ' Note:  this method should be coded as follows:
  820. '   Private Sub Form_Load()
  821. '       MyVBOFCollection.pvtDBGridSetNumberOfRows _
  822. '           DBGrid=MyDBGrid
  823. '   End Sub
  824.  
  825.     On Local Error Resume Next
  826.     
  827. ' bullet-proofing
  828.     If IsMissing(DBGrid) Then
  829.         If pvtDBGrid Is Nothing Then
  830.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridSetNumberOfRows' method for this object because the 'DBGrid' parameter is missing."
  831.             pvtDBGridSetNumberOfRows = False
  832.             Exit Function
  833.         End If
  834.     Else
  835.         Set pvtDBGrid = DBGrid
  836.     End If
  837.  
  838.     pvtDBGrid.RowBuffer.RowCount = _
  839.         pvtCollection.Count
  840.  
  841. End Function
  842.  
  843. Public Property Get pvtDBGridBookmark(DBGrid As Variant) As Variant
  844. ' Returns the Bookmark value of the DBGrid
  845. ' Using this method:
  846. '       myObjectID = _
  847. '           MyCollection.pvtDBGridBookmark _
  848. '               (DBGrid1)
  849.                 
  850.     Dim tempBookmark As Variant
  851.     
  852.     On Local Error Resume Next
  853.     
  854. ' bullet-proofing
  855.     If IsMissing(DBGrid) Then
  856.         If pvtDBGrid Is Nothing Then
  857.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridBookmark' method for this object because the 'DBGrid' parameter is missing."
  858.             pvtDBGridBookmark = -1
  859.             Exit Property
  860.         End If
  861.     Else
  862.         Set pvtDBGrid = DBGrid
  863.     End If
  864.  
  865.     tempBookmark = _
  866.         pvtDBGrid.Bookmark
  867.     
  868.     If Err = 0 Then
  869.         pvtDBGridBookmark = _
  870.             tempBookmark
  871.     Else
  872.         pvtDBGridBookmark = Null
  873.     End If
  874.  
  875. End Property
  876.  
  877. Public Property Let pvtDBGridBookmark(DBGrid As Variant, Bookmark As Variant)
  878. ' Sets the Bookmark value of the DBGrid
  879. ' Using this method:
  880. '       MyCollection.pvtDBGridBookmark _
  881. '           (DBGrid1) = MyBookMark
  882.     
  883.     On Local Error Resume Next
  884.     
  885. ' bullet-proofing
  886.     If IsMissing(DBGrid) Or IsMissing(Bookmark) Then
  887.         If pvtDBGrid Is Nothing Then
  888.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridBookmark' method for this object because the 'DBGrid' or 'Bookmark' parameter is missing."
  889.             Exit Property
  890.         End If
  891.     Else
  892.         Set pvtDBGrid = DBGrid
  893.     End If
  894.  
  895.     pvtDBGrid.Bookmark = Bookmark
  896.  
  897. End Property
  898.  
  899.  
  900. Public Property Get pvtDBGridBookmarkObject(DBGrid As Variant) As Variant
  901. ' Returns the Object at the Bookmark value of the
  902. '   DBGrid
  903. ' Using this method:
  904. '       MyObject = _
  905. '           MyCollection.pvtDBGridBookmarkObject _
  906. '               (DBGrid1)
  907.                 
  908.     Dim tempBookmark As Variant
  909.     
  910.     On Local Error Resume Next
  911.     
  912. ' bullet-proofing
  913.     If IsMissing(DBGrid) Then
  914.         If pvtDBGrid Is Nothing Then
  915.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridBookmarkObject' method for this object because the 'DBGrid' parameter is missing."
  916.             Set pvtDBGridBookmarkObject = Nothing
  917.             Exit Property
  918.         End If
  919.     Else
  920.         Set pvtDBGrid = DBGrid
  921.     End If
  922.  
  923.     tempBookmark = _
  924.         pvtDBGridBookmark(pvtDBGrid)
  925.     
  926. ' translate the Bookmark into an Item in the
  927. '   Collection
  928.     If Not IsNull(tempBookmark) Then
  929.         Set pvtDBGridBookmarkObject = ( _
  930.             pvtCollection.Item( _
  931.                 CollectionIndex( _
  932.                     Key:=pvtDBGridObjectIDAtBookmark _
  933.                         (tempBookmark))))
  934.     Else
  935.         Set pvtDBGridBookmarkObject = _
  936.             Nothing
  937.     End If
  938.  
  939. End Property
  940.  
  941. Public Property Set pvtDBGridBookmarkObject(DBGrid As Variant, Object As Variant)
  942. ' Sets the Bookmark of the DBGrid to the position
  943. '   of Object
  944. ' Using this method:
  945. '       Set MyCollection.pvtDBGridBookmarkObject _
  946. '           (DBGrid1) = MyObject
  947.                 
  948.     Dim tempLong As Long
  949.     Dim tempBookmark As Variant
  950.     Dim tempRow As Long
  951.     
  952.     On Local Error Resume Next
  953.     
  954. ' bullet-proofing
  955.     If IsMissing(DBGrid) Or IsMissing(Object) Then
  956.         If pvtDBGrid Is Nothing Then
  957.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtDBGridBookmarkObject' method for this object because the 'DBGrid' or 'Object' parameter is missing."
  958.             Exit Property
  959.         End If
  960.     Else
  961.         Set pvtDBGrid = DBGrid
  962.     End If
  963.  
  964. ' translate Object.ObjectID to a Bookmark
  965.     tempLong = Object.ObjectID
  966.     If tempLong >= 0 Then
  967.         tempRow = _
  968.             pvtDBGridRowIndexAtObjectID( _
  969.                 CStr(tempLong))
  970.                 
  971.         pvtDBGrid.Row = tempRow
  972.                 
  973.         pvtDBGrid.Bookmark = _
  974.             pvtDBGridBookmarkAtRowIndex _
  975.                 (tempRow)
  976.     End If
  977. End Property
  978.  
  979.  
  980. Public Property Get pvtListBoxListIndex(ListBox As Variant) As Long
  981. ' Returns the ListBox's ListIndex
  982. ' Note:  this method should be used as follows:
  983. '       MyListIndex = _
  984. '           MyVBOFCollection.pvtListBoxListIndex _
  985. '               (MyListBox)
  986.         
  987.     On Local Error Resume Next
  988.     
  989. ' bullet-proofing
  990.     If IsMissing(ListBox) Then
  991.         If pvtListBox Is Nothing Then
  992.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxListIndex' method for this object because the 'ListBox' or 'ListIndex' parameter is missing."
  993.             Exit Property
  994.         End If
  995.     Else
  996.         Set pvtListBox = ListBox
  997.     End If
  998.  
  999.     pvtListBoxListIndex = _
  1000.         pvtListBox.ListIndex
  1001.  
  1002. End Property
  1003.  
  1004.  
  1005. Public Property Let pvtListBoxListIndex(ListBox As Variant, ByVal ListIndex As Long)
  1006. ' Sets the ListBox's ListIndex
  1007. ' Note:  this method should be used as follows:
  1008. '       MyVBOFCollection.pvtListBoxListIndex _
  1009. '               (MyListBox) = MyListIndex
  1010.         
  1011.     On Local Error Resume Next
  1012.     
  1013. ' bullet-proofing
  1014.     If IsMissing(ListBox) Or IsMissing(ListIndex) Then
  1015.         If pvtListBox Is Nothing Then
  1016.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxListIndex' method for this object because the 'ListBox' or 'ListIndex' parameter is missing."
  1017.             Exit Property
  1018.         End If
  1019.     Else
  1020.         Set pvtListBox = ListBox
  1021.     End If
  1022.  
  1023.     If pvtListBox.ListCount > 0 _
  1024.     And pvtListBox.ListCount >= ListIndex Then
  1025.         pvtListBox.ListIndex = ListIndex
  1026.     Else
  1027.         pvtListBox.ListIndex = -1
  1028.     End If
  1029.     
  1030. End Property
  1031.  
  1032. Public Property Get pvtComboBoxText(ComboBox As Variant) As String
  1033. ' Returns the ComboBox's Text property
  1034. ' Note:  this method should be used as follows:
  1035. '       MyString = _
  1036. '           MyVBOFCollection.pvtComboBoxText (ComboBox1)
  1037.         
  1038.     On Local Error Resume Next
  1039.     
  1040. ' bullet-proofing
  1041.     If IsMissing(ComboBox) Then
  1042.         If pvtListBox Is Nothing Then
  1043.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtComboBoxText' method for this object because the 'ComboBox' parameter is missing."
  1044.             pvtComboBoxText = ""
  1045.             Exit Property
  1046.         End If
  1047.     Else
  1048.         Set pvtListBox = ComboBox
  1049.     End If
  1050.  
  1051.     pvtComboBoxText = pvtListBox.Text
  1052.  
  1053. End Property
  1054.  
  1055. Public Property Let pvtComboBoxText(ComboBox As Variant, Text As String)
  1056. ' Sets the ComboBox's Text property
  1057. ' Note:  this method should be used as follows:
  1058. '       MyVBOFCollection.pvtComboBoxText (ComboBox1) = _
  1059. '           MyString
  1060.         
  1061.     On Local Error Resume Next
  1062.     
  1063. ' bullet-proofing
  1064.     If IsMissing(ComboBox) Then
  1065.         If pvtListBox Is Nothing Then
  1066.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtComboBoxText' method for this object because the 'ComboBox' parameter is missing."
  1067.             Exit Property
  1068.         End If
  1069.     Else
  1070.         Set pvtListBox = ComboBox
  1071.     End If
  1072.  
  1073.     pvtListBox.Text = Text
  1074.  
  1075. End Property
  1076.  
  1077.  
  1078.  
  1079. Public Function pvtListBoxListCount(Optional ListBox As Variant) As Long
  1080. ' Returns the ListBox's ListCount property
  1081. ' Note:  this method should be used as follows:
  1082. '       MyListCount = _
  1083. '           MyVBOFCollection.pvtListBoxListCount (MyListBox)
  1084.         
  1085.     On Local Error Resume Next
  1086.     
  1087. ' bullet-proofing
  1088.     If IsMissing(ListBox) Then
  1089.         If pvtListBox Is Nothing Then
  1090.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxListCount' method for this object because the 'ListBox' parameter is missing."
  1091.             pvtListBoxListCount = -1
  1092.             Exit Function
  1093.         End If
  1094.     Else
  1095.         Set pvtListBox = ListBox
  1096.     End If
  1097.  
  1098.     pvtListBoxListCount = pvtListBox.ListCount
  1099.  
  1100. End Function
  1101.  
  1102. Public Function pvtListBoxRefresh(Optional ListBox As Variant) As Boolean
  1103. ' Refreshes the display of the ListBox
  1104. ' Note:  this method should be coded as follows:
  1105. '       MyVBOFCollection.pvtListBoxRefresh _
  1106. '          MyListBox
  1107.  
  1108.     On Local Error Resume Next
  1109.     
  1110. ' bullet-proofing
  1111.     If IsMissing(ListBox) Then
  1112.         If pvtListBox Is Nothing Then
  1113.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxRefresh' method for this object because the 'ListBox' parameter is missing."
  1114.             Set pvtListBoxRemoveItem = False
  1115.             Exit Function
  1116.         End If
  1117.     Else
  1118.         Set pvtListBox = ListBox
  1119.     End If
  1120.  
  1121. ' clear and populate the ListBox
  1122.     pvtListBoxClear ListBox
  1123.     pvtListBoxAddItems ListBox
  1124.  
  1125.     pvtListBoxRefresh = True
  1126. End Function
  1127.  
  1128. Public Property Get pvtListBoxTopIndex(ListBox As Variant) As Long
  1129. ' Returns the ListBox's TopIndex property
  1130. ' Note:  this method should be used as follows:
  1131. '       MyTopIndex = _
  1132. '           MyVBOFCollection.pvtListBoxTopIndex _
  1133. '               (MyListBox)
  1134.         
  1135.     On Local Error Resume Next
  1136.     
  1137. ' bullet-proofing
  1138.     If IsMissing(ListBox) Then
  1139.         If pvtListBox Is Nothing Then
  1140.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxTopIndex' method for this object because the 'ListBox' parameter is missing."
  1141.             pvtListBoxTopIndex = -1
  1142.             Exit Property
  1143.         End If
  1144.     Else
  1145.         Set pvtListBox = ListBox
  1146.     End If
  1147.  
  1148.     pvtListBoxTopIndex = pvtListBox.TopIndex
  1149. End Property
  1150.  
  1151. Public Property Let pvtListBoxTopIndex(ListBox As Variant, ListIndex As Long)
  1152. ' Sets the ListBox's TopIndex property to ListIndex
  1153. ' Note:  this method should be used as follows:
  1154. '     MyVBOFCollection.pvtListBoxTopIndex _
  1155. '         (MyListBox) = MyTopIndex
  1156.         
  1157.     On Local Error Resume Next
  1158.     
  1159. ' bullet-proofing
  1160.     If IsMissing(ListBox) Then
  1161.         If pvtListBox Is Nothing Then
  1162.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxTopIndex' method for this object because the 'ListBox' parameter is missing."
  1163.             Exit Property
  1164.         End If
  1165.     Else
  1166.         Set pvtListBox = ListBox
  1167.     End If
  1168.     If IsMissing(ListIndex) Then
  1169.         pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxTopIndex' method for this object because the 'ListIndex' parameter is missing."
  1170.         Exit Property
  1171.     End If
  1172.  
  1173.     pvtListBox.TopIndex = ListIndex
  1174. End Property
  1175.  
  1176.  
  1177. Public Property Get pvtListBoxTopObject(ListBox As Variant) As Variant
  1178. ' Returns the Object at the ListBox's TopIndex property
  1179. ' Note:  this method should be used as follows:
  1180. '       Set MyTopObject = _
  1181. '           MyVBOFCollection.pvtListBoxTopObject (MyListBox)
  1182.         
  1183.     On Local Error Resume Next
  1184.     
  1185. ' bullet-proofing
  1186.     If IsMissing(ListBox) Then
  1187.         If pvtListBox Is Nothing Then
  1188.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxTopIndex' method for this object because the 'ListBox' parameter is missing."
  1189.             Set pvtListBoxTopObject = Nothing
  1190.             Exit Property
  1191.         End If
  1192.     Else
  1193.         Set pvtListBox = ListBox
  1194.     End If
  1195.  
  1196.     Set pvtListBoxTopObject = _
  1197.         pvtCollection.Item(pvtListBox.TopIndex + 1)
  1198. End Property
  1199.  
  1200. Public Property Set pvtListBoxTopObject(ListBox As Variant, Object As Variant)
  1201. ' Sets the ListBox's TopIndex property to be the
  1202. '   index of Object
  1203. ' Note:  this method should be used as follows:
  1204. '       Set MyVBOFCollection. _
  1205. '           pvtListBoxTopObject (MyListBox) = _
  1206. '               MyTopObject
  1207.     
  1208.     Dim tempLong As Long
  1209.     
  1210.     On Local Error Resume Next
  1211.     
  1212. ' bullet-proofing
  1213.     If IsMissing(ListBox) Then
  1214.         If pvtListBox Is Nothing Then
  1215.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxTopIndex' method for this object because the 'ListBox' parameter is missing."
  1216.             Exit Property
  1217.         End If
  1218.     Else
  1219.         Set pvtListBox = ListBox
  1220.     End If
  1221.  
  1222.     tempLong = _
  1223.         CollectionIndex(Item:=Object)
  1224.  
  1225.     If tempLong > 0 Then
  1226.         pvtListBox.TopIndex = tempLong + 1
  1227.     End If
  1228. End Property
  1229.  
  1230.  
  1231. Public Property Get pvtListBoxListIndexObject(ListBox As Variant) As Variant
  1232. ' Returns the object at the ListBox's ListIndex
  1233. ' Note:  this method should be coded as follows:
  1234. '   Private Sub MyListBox_Click()
  1235. '       Dim MyObject as MyObject
  1236. '       MyObject = _
  1237. '           MyVBOFCollection.pvtListBoxListIndexObject _
  1238. '               (MyListBox)
  1239. '   End Sub
  1240.  
  1241.     On Local Error Resume Next
  1242.     
  1243. ' bullet-proofing
  1244.     If IsMissing(ListBox) Then
  1245.         If pvtListBox Is Nothing Then
  1246.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxListIndexObject' method for this object because the 'ListBox' parameter is missing."
  1247.             Set pvtListBoxListIndexObject = Nothing
  1248.             Exit Property
  1249.         End If
  1250.     Else
  1251.         Set pvtListBox = ListBox
  1252.     End If
  1253.  
  1254.     If pvtListBox.ListIndex >= 0 _
  1255.     And pvtCollection.Count >= pvtListBox.ListIndex + 1 Then
  1256.         Set pvtListBoxListIndexObject = _
  1257.             pvtCollection.Item(pvtListBox.ListIndex + 1)
  1258.     Else
  1259.         Set pvtListBoxListIndexObject = Nothing
  1260.     End If
  1261.  
  1262. End Property
  1263.  
  1264. Public Property Set pvtListBoxListIndexObject(ListBox As Variant, Object As Variant)
  1265. ' Sets the ListBox's ListIndex to correspond to the
  1266. '   Object and returns the selected Object
  1267. ' Note:  this method should be coded as follows:
  1268. '   Private Sub MyListBox_Click()
  1269. '       Dim MyObject as MyObject
  1270. '       Set MyVBOFCollection.pvtListBoxListIndexObject _
  1271. '               (MyListBox) = MyObject
  1272. '   End Sub
  1273.  
  1274.     On Local Error Resume Next
  1275.     
  1276. ' bullet-proofing
  1277.     If IsMissing(ListBox) Or IsMissing(Object) Then
  1278.         If pvtListBox Is Nothing Then
  1279.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxListIndexObject' method for this object because the 'ListBox' or 'Object' parameter is missing."
  1280.             Exit Property
  1281.         End If
  1282.     Else
  1283.         Set pvtListBox = ListBox
  1284.     End If
  1285.  
  1286.     pvtListBox.ListIndex = _
  1287.         CollectionIndex(Item:=Object)
  1288. End Property
  1289.  
  1290.  
  1291. Public Function pvtListBoxAddItems(Optional ListBox As Variant) As Boolean
  1292. ' Populates the ListBox with one line of information
  1293. '   for each object in this VBOFCollection
  1294. ' Note:  the referenced objects must contain the
  1295. '   method 'ObjectListBoxValue', which must return
  1296. '   a String which is the text which is to appear
  1297. '   in the ListBox and is to represent the object
  1298. '   for the purposes of the ListBox.
  1299. ' Note:  this method should be coded as follows:
  1300. '    MyVBOFCollection.pvtListBoxAddItems MyListBox
  1301.  
  1302.     Dim tempObject As Object
  1303.     Dim tempListBoxText As String
  1304.     Dim tempListBox As Variant
  1305.     
  1306.     On Local Error Resume Next
  1307.     
  1308. ' bullet-proofing
  1309.     If IsMissing(ListBox) Then
  1310.         If pvtListBox Is Nothing Then
  1311.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxAddItems' method for this object because the 'ListBox:=' parameter is missing."
  1312.             pvtListBoxAddItems = False
  1313.             GoTo pvtListBoxAddItems_Exit
  1314.         End If
  1315.     Else
  1316.         Set pvtListBox = ListBox
  1317.     End If
  1318.         
  1319. #If NoDebugMode = False Then
  1320.     If pvtVBOFObjectManager.DebugMode Then
  1321.         pvtVBOFObjectManager.DisplayDebugMessage _
  1322.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has begun '.pvtListBoxAddItems' processing"
  1323.     End If
  1324. #End If
  1325.  
  1326. ' .AddItem each object into the ListBox
  1327.     For Each tempObject In pvtCollection
  1328.         pvtListBox.AddItem _
  1329.             tempObject.ObjectListBoxValue()
  1330.     Next tempObject
  1331.  
  1332.     pvtListBoxAddItems = True
  1333.     GoTo pvtListBoxAddItems_Exit
  1334.  
  1335. pvtListBoxAddItems_Exit:
  1336.     Set tempObject = Nothing
  1337.     Set tempListBox = Nothing
  1338.  
  1339. End Function
  1340.  
  1341. Public Function pvtListBoxClear(Optional ListBox As Variant, Optional NoDelete As Variant) As Boolean
  1342. ' Empties the objects from the ListBox and removes
  1343. '   the corresponding objects from the Collection
  1344. ' Note:  this method should be coded as follows:
  1345. '     MyVBOFCollection.pvtListBoxClear _
  1346. '               MyListBox
  1347. ' Note:
  1348. '   In order to actually remove the containment
  1349. '       links from the containing object to the
  1350. '       items in the ListBox, specify
  1351. '       NoDelete:=False
  1352.  
  1353.     Dim tempObject As Object
  1354.         
  1355.     On Local Error Resume Next
  1356.     
  1357. ' bullet-proofing
  1358.     If IsMissing(ListBox) Then
  1359.         If pvtListBox Is Nothing Then
  1360.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxClear' method for this object because the 'ListBox:=' parameter is missing."
  1361.             pvtListBoxClear = False
  1362.             GoTo pvtListBoxClear_Exit
  1363.         End If
  1364.     Else
  1365.         Set pvtListBox = ListBox
  1366.     End If
  1367.     
  1368. ' clear the ListBox
  1369.     pvtListBox.Clear
  1370.  
  1371. ' .RemoveObject for each object in the Collection
  1372.     If Not IsMissing(NoDelete) Then
  1373.         If Not NoDelete Then     ' doesn't work when ANDed with line above
  1374.             For Each tempObject In pvtCollection
  1375.                 pvtVBOFObjectManager.RemoveObject _
  1376.                     Object:=tempObject, _
  1377.                     Parent:=Me, _
  1378.                     NoDelete:=NoDelete
  1379.             Next tempObject
  1380.         End If
  1381.     End If
  1382.  
  1383.     pvtListBoxClear = True
  1384.     GoTo pvtListBoxClear_Exit
  1385.  
  1386. pvtListBoxClear_Exit:
  1387.     Set tempObject = Nothing
  1388. End Function
  1389. Public Function pvtListBoxRemoveObject(Optional ListBox As Variant, Optional Object As Variant) As Boolean
  1390. ' Removes the specified Object from the ListBox
  1391. ' Note:  this method should be coded as follows:
  1392. '       Dim MyUndesiredObject As MyClass
  1393. '       MyVBOFCollection.pvtListBoxRemoveObject _
  1394. '          MyListBox, MyUndesiredObject
  1395.  
  1396.     Dim tempIndex As Long
  1397.  
  1398.     On Local Error Resume Next
  1399.     
  1400. ' bullet-proofing
  1401.     If IsMissing(ListBox) Then
  1402.         If pvtListBox Is Nothing Then
  1403.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxSelectObject' method for this object because the 'ListBox' parameter is missing."
  1404.             pvtListBoxRemoveObject = False
  1405.             Exit Function
  1406.         End If
  1407.     Else
  1408.         Set pvtListBox = ListBox
  1409.     End If
  1410.     If IsMissing(Object) Then
  1411.         pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxSelectObject' method for this object because the 'Object' parameter is missing."
  1412.         pvtListBoxRemoveObject = False
  1413.         Exit Function
  1414.     End If
  1415.  
  1416. ' find the Object
  1417.     tempIndex = _
  1418.         CollectionIndex(Item:=Object)
  1419.  
  1420.     If tempIndex <= 0 Then
  1421.         pvtListBoxRemoveObject = False
  1422.         Exit Function
  1423.     End If
  1424.  
  1425. ' remove the Object from the Collection
  1426.     Remove _
  1427.         Item:=Object, _
  1428.         NoDelete:=True
  1429.  
  1430. ' remove the Object from the ListBox
  1431.     pvtListBox.RemoveItem _
  1432.         tempIndex - 1
  1433.         
  1434.     pvtListBoxRemoveObject = True
  1435. End Function
  1436.  
  1437.  
  1438.  
  1439. Public Function pvtListBoxRemoveItem(Optional ListBox As Variant, Optional ListIndex As Variant) As Boolean
  1440. ' Removes the Object at the specified ListIndex
  1441. '   from the ListBox
  1442. ' Note:  this method should be coded as follows:
  1443. '       Dim MyUndesiredListIndex As Long
  1444. '       MyVBOFCollection.pvtListBoxRemoveItem _
  1445. '          MyListBox, MyUndesiredListIndex
  1446.  
  1447.     Dim tempObject As Object
  1448.  
  1449.     On Local Error Resume Next
  1450.     
  1451. ' bullet-proofing
  1452.     If IsMissing(ListBox) Then
  1453.         If pvtListBox Is Nothing Then
  1454.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxSelectObject' method for this object because the 'ListBox' parameter is missing."
  1455.             pvtListBoxRemoveItem = False
  1456.             Exit Function
  1457.         End If
  1458.     Else
  1459.         Set pvtListBox = ListBox
  1460.     End If
  1461.     If IsMissing(ListIndex) Then
  1462.         pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxSelectObject' method for this object because the 'ListIndex'  parameter is missing."
  1463.         pvtListBoxRemoveItem = False
  1464.         Exit Function
  1465.     End If
  1466.  
  1467. ' find the Object
  1468.     Set tempObject = _
  1469.         pvtCollection.Item(ListIndex + 1)
  1470.  
  1471.     If tempObject Is Nothing Then
  1472.         pvtListBoxRemoveItem = False
  1473.         Exit Function
  1474.     End If
  1475.  
  1476. ' remove the Object from the Collection
  1477.     Remove _
  1478.         Item:=tempObject, _
  1479.         NoDelete:=True
  1480.  
  1481. ' remove the Object from the ListBox
  1482.     pvtListBox.RemoveItem _
  1483.         ListIndex
  1484.         
  1485.     pvtListBoxRemoveItem = True
  1486.     Set tempObject = Nothing
  1487. End Function
  1488.  
  1489.  
  1490. Public Property Get pvtListBoxSelectedObjects(ListBox As Variant) As Collection
  1491. ' Returns a collection of the selected objects
  1492. '   of the specified ListBox
  1493. ' Note:  this method should be coded as follows:
  1494. '   Private Sub MyListBox_Click()
  1495. '       Dim MyCollection As Collection
  1496. '       Set MyCollection = _
  1497. '           MyVBOFCollection.pvtListBoxSelectedObjects _
  1498. '               (MyListBox)
  1499. '   End Sub
  1500.     
  1501.     Dim tempCollection As New Collection
  1502.     Dim tempObject As Object
  1503.     Dim I As Long
  1504.         
  1505.     On Local Error Resume Next
  1506.     
  1507. ' bullet-proofing
  1508.     If IsMissing(ListBox) Then
  1509.         If pvtListBox Is Nothing Then
  1510.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxSelectedObjects' method for this object because the 'ListBox' parameter is missing."
  1511.             Set pvtListBoxSelectedObjects = Nothing
  1512.             Exit Property
  1513.         End If
  1514.     Else
  1515.         Set pvtListBox = ListBox
  1516.     End If
  1517.  
  1518. ' collect all selected objects
  1519.     I = 0
  1520.     For Each tempObject In pvtCollection
  1521.         If pvtListBox.Selected(I) Then
  1522.             tempCollection.Add tempObject
  1523.         End If
  1524.         
  1525.         I = I + 1
  1526.     Next tempObject
  1527.  
  1528.     Set pvtListBoxSelectedObjects = tempCollection
  1529.     Set tempObject = Nothing
  1530. End Property
  1531.  
  1532.  
  1533. Public Property Set pvtListBoxSelectedObjects(ListBox As Variant, Collection As Collection)
  1534. ' Sets the selected objects of the specified
  1535. '   ListBox to the contents of Collection
  1536. ' Note:  this method should be coded as follows:
  1537. '       Dim MyCollection As Collection
  1538. '       MyVBOFCollection.pvtListBoxSelectedObjects _
  1539. '               (MyListBox) = MyCollection
  1540.     
  1541.     Dim tempObject As Object
  1542.     Dim tempIndex As Long
  1543.     Dim I As Long
  1544.     
  1545.     On Local Error Resume Next
  1546.     
  1547. ' bullet-proofing
  1548.     If IsMissing(ListBox) Or IsMissing(Collection) Then
  1549.         If pvtListBox Is Nothing Then
  1550.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxSelectedObjects' method for this object because the 'ListBox' or 'Collection' parameter is missing."
  1551.             Exit Property
  1552.         End If
  1553.     Else
  1554.         Set pvtListBox = ListBox
  1555.     End If
  1556.  
  1557. ' unselect any currently selected rows
  1558.     For I = 0 To pvtListBox.ListCount - 1
  1559.         pvtListBox.Selected(I) = False
  1560.     Next I
  1561.  
  1562. ' select those rows whose corresponding objects
  1563. '   appear in Collection
  1564.     For Each tempObject In Collection
  1565.         tempIndex = _
  1566.             CollectionIndex(Item:=tempObject)
  1567.             
  1568.         If tempIndex > 0 Then
  1569.             pvtListBox.Selected(tempIndex - 1) = True
  1570.         End If
  1571.         
  1572.     Next tempObject
  1573.     
  1574.     Set tempObject = Nothing
  1575. End Property
  1576.  
  1577.  
  1578.  
  1579.  
  1580. Public Function Add( _
  1581.     Optional Item As Variant, _
  1582.     Optional Object As Variant, _
  1583.     Optional Key As Variant, _
  1584.     Optional Parent As Variant, _
  1585.     Optional After As Variant, _
  1586.     Optional NoInsert As Variant, _
  1587.     Optional NoRefresh As Variant) As Variant
  1588. ' Add the new Item to the collection and
  1589. '   return the collection.
  1590. ' Note: Item might be freed by VBOFObjectManager
  1591. '   if it is found to be non-unique throughout the
  1592. '   environment.  For more information, refer to
  1593. '   the VBOF User's Guide.
  1594.  
  1595.     Dim tempSuppressInsert As Boolean
  1596.     Dim tempObject As Object
  1597.     Dim tempSpecifiedParameterObject As Object
  1598.     Dim tempParameterObjectWasSpecified As Boolean
  1599.     Dim tempFoundInFirstPass As Boolean
  1600.     Dim tempNoRefresh As Boolean
  1601.  
  1602.     On Local Error Resume Next
  1603.     Set Add = Nothing
  1604.         
  1605. ' bullet-proofing
  1606.     tempParameterObjectWasSpecified = _
  1607.         ObjectManager.pvtChooseObjectFromParameters( _
  1608.             Item:=Item, _
  1609.             Object:=Object, _
  1610.             ReturnObject:=tempSpecifiedParameterObject)
  1611.     If Not tempParameterObjectWasSpecified _
  1612.     Or tempSpecifiedParameterObject Is Nothing _
  1613.     Then
  1614. '    If IsMissing(Item) Then
  1615.         pvtErrorMessage TypeName(Me) & " cannot process the '.Add' method for this object because both the 'Item:=' and 'Object:=' parameters are missing.  One of these must be specified."
  1616.         GoTo Add_Exit
  1617.     End If
  1618.     If Not pvtSetParent( _
  1619.             Parent:=Parent, _
  1620.             MethodName:="Add") Then
  1621.         GoTo Add_Exit
  1622.     End If
  1623.     tempNoRefresh = False
  1624.     If Not IsMissing(NoRefresh) Then
  1625.         If NoRefresh Then
  1626.             tempNoRefresh = True
  1627.         End If
  1628.     End If
  1629.     
  1630. ' support database-free emulation of the VB Collection Class
  1631.     tempSuppressInsert = False
  1632.     If tempSpecifiedParameterObject.ObjectDataSource = "" _
  1633.     Or Err = 438 Then
  1634.         pvtCollectionEmulationMode = True
  1635.         tempSuppressInsert = True
  1636.     End If
  1637.     If Not IsMissing(NoInsert) Then
  1638.         If NoInsert = True Then
  1639.             tempSuppressInsert = True
  1640.         End If
  1641.     End If
  1642.         
  1643. ' verify that the object is unique across
  1644. '   the known system objects
  1645. '   (First pass.  Works only when adding
  1646. '   Object to a subsequent Collection)
  1647.     tempFoundInFirstPass = False
  1648.     Set tempObject = _
  1649.         pvtVBOFObjectManager.pvtAddUniqueObject _
  1650.             (Object:=tempSpecifiedParameterObject)
  1651.     If Not pvtVBOFObjectManager.pvtObjectWasUnique Then
  1652.         tempFoundInFirstPass = True
  1653.     End If
  1654.  
  1655. '>>if tempObject= is moved, change tempObject.*
  1656. '   to Item.* down to "where tempObject= used to be"
  1657.  
  1658. ' if in an Insert-capable mode
  1659.     If Not tempSuppressInsert _
  1660.     And Not tempFoundInFirstPass Then
  1661.  
  1662. ' if Item.ObjectID doesn't already have a value
  1663. '   (meaning that it has never been inserted in
  1664. '   the database),
  1665.         If tempObject.ObjectID <= 0 Then
  1666.         
  1667. ' insert Item and set Item.ObjectID
  1668.             tempObject.ObjectID = _
  1669.                 pvtDBInsert( _
  1670.                     Item:=tempObject)
  1671.         End If
  1672.  
  1673. ' else, if the ObjectID doesn't already have a value
  1674. '   assign an artificial ObjectID
  1675. '    Else
  1676.     ElseIf Not tempFoundInFirstPass Then
  1677.         tempObject.ObjectID = _
  1678.             pvtVBOFObjectManager.pvtNextObjectID
  1679.     End If
  1680.             
  1681. ' save the HighestObjectID encountered
  1682.     pvtVBOFObjectManager.pvtSaveHighestObjectID _
  1683.         tempObject.ObjectID
  1684.         
  1685. ' verify that the object is unique across
  1686. '   the known system objects
  1687. '   (Second pass.  Finds redundantly inserted
  1688. '   Objects)
  1689.     If Not tempFoundInFirstPass Then
  1690.         Set tempObject = _
  1691.             pvtVBOFObjectManager.pvtAddUniqueObject _
  1692.                     (Object:=tempObject)
  1693.     End If
  1694.  
  1695. ' use the Key:= if it was provided and it was
  1696. '   of Type(Long)
  1697.     If IsMissing(Key) Or Key = 0 Or Err = 13 Then
  1698.         pvtAddItemToCollection _
  1699.             Item:=tempObject, _
  1700.             Key:=CStr(tempObject.ObjectID), _
  1701.             After:=After
  1702.  
  1703. ' else, use the Item.ObjectID
  1704.     Else
  1705.         pvtAddItemToCollection _
  1706.             Item:=tempObject, _
  1707.             Key:=Key, _
  1708.             After:=After
  1709.     End If
  1710.  
  1711. ' link the Item to its Parent object
  1712. '   (in the database)
  1713.     If pvtCollectionEmulationMode = False Then
  1714.         RC = pvtLinkParentToChildObject( _
  1715.                 Parent:=pvtParent, _
  1716.                 Child:=tempObject)
  1717.         
  1718.         If Not tempNoRefresh Then
  1719.             pvtRefreshRecordSet
  1720.         End If
  1721.     End If
  1722.  
  1723. #If NoDebugMode = False Then
  1724.     If pvtVBOFObjectManager.DebugMode Then
  1725.         pvtVBOFObjectManager.DisplayDebugMessage _
  1726.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has added  ObjectType=" & _
  1727.             TypeName(tempObject) & _
  1728.             ", ObjectID=" & _
  1729.             tempObject.ObjectID
  1730.     End If
  1731. #End If
  1732.  
  1733. ' trigger the "Added" event for the new object
  1734. #If NoEventMgr = False Then
  1735.     TriggerCollectionEvent _
  1736.         Object:=tempObject, _
  1737.         Event:="AddedItem"
  1738. #End If
  1739.         
  1740.     Set Add = tempObject
  1741.     GoTo Add_Exit
  1742.  
  1743. Add_Exit:
  1744.     Set pvtMostRecentlyAddedObject = tempObject
  1745.     Set tempObject = Nothing
  1746. End Function
  1747. Private Function pvtLinkParentToChildObject(Optional Parent As Variant, Optional Child As Variant) As Long
  1748.  
  1749.     Dim SQLStatement As String
  1750.     
  1751.     On Local Error Resume Next
  1752.     
  1753.     If pvtCollectionEmulationMode Then
  1754.         pvtLinkParentToChildObject = True
  1755.     End If
  1756.  
  1757. ' insert a row into the VBObjectFrameworkObjectLinks table
  1758.     SQLStatement = _
  1759.         "INSERT INTO " & ObjectDataSource() & " " & _
  1760.         "(FromObjectType" & _
  1761.         ",FromObjectID" & _
  1762.         ",ToObjectType" & _
  1763.         ",ToObjectID"
  1764.     SQLStatement = SQLStatement & _
  1765.         ") VALUES " & _
  1766.         "('" & TypeName(Parent) & "'" & _
  1767.         ", " & Parent.ObjectID & "" & _
  1768.         ",'" & TypeName(Child) & "'" & _
  1769.         ", " & Child.ObjectID & ""
  1770.     SQLStatement = SQLStatement & _
  1771.         ")"
  1772.     
  1773.     pvtDatabase.Execute SQLStatement, pvtODBCPassThrough
  1774.     If Err <> 0 Then '
  1775.         pvtErrorMessage TypeName(Me) & " received a database error while attempting to establish an object containment link (Insert).  SQL=" & SQLStatement
  1776.         pvtLinkParentToChildObject = False
  1777.         Exit Function
  1778.     End If
  1779.         
  1780.     pvtLinkParentToChildObject = True
  1781. End Function
  1782.  
  1783.  
  1784. Public Property Get MostRecentlyAddedObject() As Variant
  1785. Attribute MostRecentlyAddedObject.VB_Description = "Returns the most recently added object"
  1786. ' Returns the Object most recently added to the
  1787. '   VBOFCollection
  1788.  
  1789.     Set MostRecentlyAddedObject = _
  1790.         pvtMostRecentlyAddedObject
  1791.  
  1792. End Property
  1793.  
  1794. Public Property Get MostRecentlyAddedObjectIndex() As Long
  1795. Attribute MostRecentlyAddedObjectIndex.VB_Description = "Returns the collection index of the most recently added object"
  1796. ' Returns the Index in the Collection of the
  1797. '   Object most recently added to the
  1798. '   VBOFCollection
  1799.  
  1800.     MostRecentlyAddedObjectIndex = _
  1801.         CollectionIndex _
  1802.             (Item:=pvtMostRecentlyAddedObject)
  1803.  
  1804. End Property
  1805.  
  1806.  
  1807.  
  1808. Public Function pvtCloneRecordSet() As RecordSet
  1809. Attribute pvtCloneRecordSet.VB_Description = "Returns a Clone of the internally maintained RecordSet object"
  1810.     Set pvtCloneRecordSet = pvtRecordSet.Clone()
  1811. End Function
  1812.  
  1813. Public Function CollectionIndex( _
  1814.     Optional Item As Variant, _
  1815.     Optional Object As Variant, _
  1816.     Optional Key As Variant, _
  1817.     Optional WhereClause As Variant, _
  1818.     Optional FindFirst As Variant, _
  1819.     Optional FindNext As Variant, _
  1820.     Optional FindLast As Variant, _
  1821.     Optional FindPrevious As Variant, _
  1822.     Optional Collection As Variant) As Long
  1823. ' Returns the Collection Index of the
  1824. '   specified Item, or the item at the specified Key
  1825. ' Program Usage:
  1826. '   Dim MyCollection as VBOFCollection
  1827. '   MyIndex = MyCollection.CollectionIndex _
  1828. '                (Item:=MyObject)
  1829. ' or
  1830. '   MyIndex = MyCollection.CollectionIndex _
  1831. '                (Key:=MyKey)
  1832. ' or
  1833. '   MyIndex = MyCollection.CollectionIndex _
  1834. '                (WhereClause:="LastName = 'Jones'")
  1835. '       (see comments in method "pvtCollectionIndexForWhereClause"
  1836. '       for important information about using the
  1837. '       WhereClause:= parameter)
  1838. ' or
  1839. '   MyIndex = MyCollection.CollectionIndex _
  1840. '                (WhereClause:="LastName = 'Jones'", _
  1841. '                 FindFirst:=True)
  1842. '       (see comments in method "pvtCollectionIndexForWhereClause"
  1843. '       for important information about using the
  1844. '       WhereClause:= parameter)
  1845. '
  1846. ' Parameters:
  1847. '   Item:= - the object whose Collection Index is
  1848. '       desired
  1849. '   Object:= - (same as Item:=)
  1850. '   Key:= - the key value of the object whose
  1851. '       Collection Index is desired
  1852. '   WhereClause:= - a search string which can be
  1853. '       appended to the RecordSet.FindNext method
  1854. '   FindNext:= - a boolean which determines whether
  1855. '       the FindNext method should be used
  1856. '       (FindNext is the default)
  1857. '   FindFirst:= - a boolean which determines whether
  1858. '       the FindFirst method should be used
  1859. '       (FindNext is the default)
  1860. '   FindLast:= - a boolean which determines whether
  1861. '       the FindLast method should be used
  1862. '       (FindNext is the default)
  1863. '   FindPrevious:= - a boolean which determines whether
  1864. '       the FindPrevious method should be used
  1865. '       (FindNext is the default)
  1866.  
  1867.     Dim tempItem As Object
  1868.     Dim I As Long
  1869.     Dim tempParameterObjectWasSpecified As Boolean
  1870.     Dim tempSpecifiedParameterObject As Variant
  1871.  
  1872.     On Local Error Resume Next
  1873.     
  1874. ' bullet-proofing
  1875.     tempParameterObjectWasSpecified = _
  1876.         ObjectManager.pvtChooseObjectFromParameters( _
  1877.             Item:=Item, _
  1878.             Object:=Object, _
  1879.             ReturnObject:=tempSpecifiedParameterObject)
  1880.     If Not tempParameterObjectWasSpecified _
  1881.     And IsMissing(Key) _
  1882.     And IsMissing(WhereClause) Then
  1883.         pvtErrorMessage TypeName(Me) & " cannot process the '.CollectionIndex' method for this object because the 'Item:=', 'Object:=', 'Key:=' and 'WhereClause:=' parameters are missing."
  1884.         CollectionIndex = -1
  1885.         GoTo CollectionIndex_Exit
  1886.     End If
  1887.     
  1888. ' branch to an appropriate private method
  1889.     If Not IsMissing(Item) Then
  1890.         CollectionIndex = _
  1891.             pvtCollectionIndexForItem( _
  1892.                 Item:=Item, _
  1893.                 Collection:=Collection)
  1894.     ElseIf Not IsMissing(Key) Then
  1895.         CollectionIndex = _
  1896.             pvtCollectionIndexForKey( _
  1897.                 Key:=Key, _
  1898.                 Collection:=Collection)
  1899.     ElseIf Not IsMissing(WhereClause) Then
  1900.         CollectionIndex = _
  1901.             pvtCollectionIndexForWhereClause( _
  1902.                 WhereClause:=WhereClause, _
  1903.                 FindFirst:=FindFirst, _
  1904.                 FindLast:=FindLast, _
  1905.                 FindNext:=FindNext, _
  1906.                 FindPrevious:=FindPrevious)
  1907.     Else
  1908.         CollectionIndex = -1
  1909.     End If
  1910.  
  1911.     GoTo CollectionIndex_Exit
  1912.     
  1913. CollectionIndex_Exit:
  1914.     Set tempItem = Nothing
  1915. End Function
  1916.  
  1917.  
  1918. Private Function pvtCollectionIndexForItem( _
  1919.     Optional Item As Variant, _
  1920.     Optional Collection As Variant) As Long
  1921. ' Returns the Collection Index of the
  1922. '   specified Item
  1923.  
  1924.     Dim tempItem As Object
  1925.     Dim I As Long
  1926.     Dim tempCollection As Collection
  1927.  
  1928.     On Local Error Resume Next
  1929.     
  1930. ' bullet-proofing
  1931.     If IsMissing(Item) Then
  1932.         pvtErrorMessage TypeName(Me) & " cannot process the '.pvtCollectionIndexForItem' method for this object because the 'Item:=' parameter is missing."
  1933.         pvtCollectionIndexForItem = -1
  1934.         Exit Function
  1935.     End If
  1936.     If Not IsMissing(Collection) Then
  1937.         Set tempCollection = Collection
  1938.     Else
  1939.         Set tempCollection = pvtCollection
  1940.     End If
  1941.     
  1942. ' search each Object in the Collection
  1943.     I = 1
  1944.     For Each tempItem In tempCollection
  1945.         If CStr(tempItem.ObjectID) = CStr(Item.ObjectID) Then
  1946.             If Err = 0 Then ' <=== VB4 Error: for some reason this doesn't work if placed in the above statement as an "And"
  1947.                 pvtCollectionIndexForItem = I
  1948.                 GoTo pvtCollectionIndexForItem_Exit
  1949.             End If
  1950.         End If
  1951.         
  1952.         I = I + 1
  1953.     Next tempItem
  1954.  
  1955.     pvtCollectionIndexForItem = -1
  1956.     GoTo pvtCollectionIndexForItem_Exit
  1957.     
  1958. pvtCollectionIndexForItem_Exit:
  1959.     Set tempItem = Nothing
  1960. End Function
  1961.  
  1962. Private Function pvtCollectionIndexForKey(Optional Key As Variant, Optional Collection As Variant) As Long
  1963. ' Returns the Collection Index of the Item at the
  1964. '   specified Key
  1965.  
  1966.     Dim tempItem As Object
  1967.     Dim I As Long
  1968.     Dim tempCollection As Collection
  1969.  
  1970.     On Local Error Resume Next
  1971.     
  1972. ' bullet-proofing
  1973.     If IsMissing(Key) Then
  1974.         pvtErrorMessage TypeName(Me) & " cannot process the '.pvtCollectionIndexForKey' method for this object because the 'Key:=' parameter is missing."
  1975.         pvtCollectionIndexForKey = -1
  1976.         Exit Function
  1977.     End If
  1978.     If Not IsMissing(Collection) Then
  1979.         Set tempCollection = Collection
  1980.     Else
  1981.         Set tempCollection = pvtCollection
  1982.     End If
  1983.     
  1984.     I = 1
  1985.     For Each tempItem In tempCollection
  1986.         If CStr(tempItem.ObjectID) = CStr(Key) Then
  1987.             If Err = 0 Then ' <=== VB4 Error: for some reason this doesn't work if placed in the above statement as an "And"
  1988.                 pvtCollectionIndexForKey = I
  1989.                 GoTo pvtCollectionIndexForKey_Exit
  1990.             End If
  1991.         End If
  1992.         
  1993.         I = I + 1
  1994.     Next tempItem
  1995.  
  1996.     pvtCollectionIndexForKey = -1
  1997.     GoTo pvtCollectionIndexForKey_Exit
  1998.     
  1999. pvtCollectionIndexForKey_Exit:
  2000.     Set tempItem = Nothing
  2001. End Function
  2002.  
  2003.  
  2004.  
  2005. Public Property Get Count() As Long
  2006. Attribute Count.VB_Description = "Returns a count of the number of items currently in the collection.  See the VB Programmer's Manual for details"
  2007. ' Returns the count of objects currently defined
  2008. '   as part of the collection
  2009.  
  2010.     Count = pvtCollection.Count
  2011. End Property
  2012.  
  2013. Public Property Get Database() As Database
  2014. Attribute Database.VB_Description = "Sets the database property"
  2015.     Set Database = pvtDatabase
  2016. End Property
  2017.  
  2018. Public Property Set Database(Database As Database)
  2019.  
  2020.     If Not IsMissing(Database) Then
  2021.         pvtReceiveGeneralParameters _
  2022.             Database:=Database
  2023.             
  2024.         pvtCollectionEmulationMode = False
  2025.     End If
  2026.  
  2027. End Property
  2028.  
  2029.  
  2030. Public Function pvtDatabaseHasBeenReferenced() As Boolean
  2031. Attribute pvtDatabaseHasBeenReferenced.VB_Description = "Returns turue or false, depending on whether or not the DBAwareCollection has referenced the database to attempt to instantiate the collection of contained objects"
  2032. ' Returns aBoolean, depending on whether or not the
  2033. '   Database has been referenced as of yet for this
  2034. '   VBOFCollection
  2035.     
  2036.     Dim tempLong As Long
  2037.     
  2038.     On Local Error Resume Next
  2039.     
  2040. ' validate the RecordSet
  2041.     tempLong = pvtRecordSet.RecordCount
  2042.     If Err = 3420 Then
  2043.         pvtDBHasBeenReferenced = False
  2044.         pvtDatabaseHasBeenReferenced = False
  2045.         Exit Function
  2046.     End If
  2047.     
  2048.     pvtDatabaseHasBeenReferenced = _
  2049.         pvtDBHasBeenReferenced
  2050. End Function
  2051.  
  2052. Private Function pvtPopulateFromDatabase(Optional Database As Variant, Optional Sample As Variant, Optional Parent As Variant, Optional WhereClause As Variant, Optional SQL As Variant, Optional OrderByClause As Variant, Optional ANSISQL As Variant, Optional ODBCPassThrough As Variant) As VBOFCollection
  2053. Attribute pvtPopulateFromDatabase.VB_Description = "Returns a DBAwareCollection which has been instantiated with a collection of instantiated objects, according to the contents of the associated table"
  2054. ' Returns a VBOFCollection of objects which have been
  2055. '   populated from data found in a database
  2056. '   table meeting the criteria specified in any of
  2057. '   the following methods:
  2058. '       a complete SQL statement can be provided;
  2059. '       a Where Clause can be provided;
  2060. '       a Parent Object can be provided
  2061. '
  2062. ' Parameter Description:
  2063. '       see VBOFObjetManager.ManageCollection
  2064.  
  2065.     Dim tempRow As Object
  2066.     Dim newChildObject As Object
  2067.     Dim tempIndex As Long
  2068.     
  2069.     On Local Error Resume Next
  2070.     
  2071.     Set pvtPopulateFromDatabase = Nothing
  2072.     pvtRecordSetProvidedByUser = False
  2073.  
  2074. ' test Sample for Database-readiness
  2075.     If Not IsMissing(Sample) Then
  2076.         If (Sample.ObjectDataSource = "" _
  2077.         Or Err = 438) Then
  2078.             pvtCollectionEmulationMode = True
  2079.         End If
  2080.     End If
  2081.  
  2082.     pvtReceiveGeneralParameters _
  2083.         Database:=Database, _
  2084.         Sample:=Sample, _
  2085.         Parent:=Parent, _
  2086.         WhereClause:=WhereClause, _
  2087.         OrderByClause:=OrderByClause, _
  2088.         ANSISQL:=ANSISQL, _
  2089.         ODBCPassThrough:=ODBCPassThrough, _
  2090.         SQL:=SQL
  2091.  
  2092. ' determine the usability of the parameters
  2093.     If Not pvtIsDatabaseSpecified() _
  2094.     Or Not pvtIsSQLAccessable() _
  2095.     Then
  2096.         Exit Function
  2097.     End If
  2098.  
  2099. ' open a RecordSet containing the desired rows
  2100.     Set pvtRecordSet = _
  2101.         pvtDBSelect(pvtCreateSQLStatement())
  2102.  
  2103. ' create the objects from the contents of the
  2104. '   RecordSet
  2105.     
  2106.     Set pvtCollection = _
  2107.         pvtInstantiateObjectsFromRecordSet( _
  2108.             RecordSet:=pvtRecordSet, _
  2109.             Collection:=pvtCollection)
  2110.  
  2111. pvtPopulateFromDatabase_Exit:
  2112. #If NoDebugMode = False Then
  2113.     If pvtVBOFObjectManager.DebugMode Then
  2114.         pvtVBOFObjectManager.DisplayDebugMessage _
  2115.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has instantiated a collection of objects from the Database.  " & _
  2116.             "Object count=" & pvtCollection.Count & ", ParentType=" & _
  2117.             TypeName(Parent) & ", ObjectID=" & _
  2118.             Parent.ObjectID & ", ChildObjectType=" & _
  2119.             TypeName(Sample)
  2120.     End If
  2121. #End If
  2122.  
  2123. ' trigger the "PopulatedFromDatabase" event for Me
  2124. #If NoEventMgr = False Then
  2125.     TriggerCollectionEvent _
  2126.         Event:="PopulatedFromDatabase"
  2127. #End If
  2128.  
  2129.     Set pvtPopulateFromDatabase = Me
  2130.     Set tempRow = Nothing
  2131.     Set newChildObject = Nothing
  2132. End Function
  2133.  
  2134.  
  2135. Private Sub pvtDBGridBookmarkArrayClear()
  2136.  
  2137.     ReDim Preserve _
  2138.         pvtDBGridBookmarkArray(1 To 2, 0)
  2139.     
  2140.     pvtDBGridBookmarkArrayAvailable = False
  2141. End Sub
  2142.  
  2143. Public Function Item( _
  2144.     Optional ObjectID As Variant, _
  2145.     Optional Object As Variant) As Variant
  2146. ' Returns either the entire collection or a
  2147. '   specific item in the collection
  2148. ' As with the standard VB Collection object,
  2149. '   if Item:= is specified, then the requested
  2150. '   object is returned (if it can be found),
  2151. '   otherwise the entire collection is returned
  2152. '
  2153. ' Examples of usage:
  2154. '    Dim tempNewPerson As New Person
  2155. '    Set Persons = _
  2156. '        MyCollection
  2157. '
  2158. '    Dim tempNewPerson As New Person
  2159. '    Set tempNewPerson = _
  2160. '        MyCollection(1)
  2161. '
  2162. '    Dim tempNewPerson As New Person
  2163. '    Set tempNewPerson = _
  2164. '        MyCollection.Item(1)
  2165. '
  2166. '    Dim tempNewPerson As New Person
  2167. '    Set tempNewPerson = _
  2168. '        MyCollection(ObjectID:=ObjectID)
  2169. '
  2170. '    Dim tempNewPerson As New Person
  2171. '    Set tempNewPerson = _
  2172. '        MyCollection(Object:=anObject)
  2173. '
  2174. '    Dim tempNewPerson As New Person
  2175. '    Set tempNewPerson = _
  2176. '        MyCollection(Item:=anObject)
  2177.  
  2178.     Dim tempObjectID As Variant
  2179.  
  2180.     On Local Error Resume Next
  2181.  
  2182. ' determine the usability of the current state
  2183.     If Not pvtCollectionEmulationMode Then
  2184.         If Not pvtIsDatabaseSpecified() _
  2185.         Or Not pvtIsSQLAccessable() _
  2186.         Or Not pvtIsCollectionInstantiated() _
  2187.         Then
  2188.             Exit Function
  2189.         End If
  2190.     End If
  2191.     
  2192. ' check for a request for a specific Object
  2193.     If ObjectManager.pvtChooseObjectIDFromParameters( _
  2194.         Object:=Object, _
  2195.         ObjectID:=ObjectID, _
  2196.         ReturnObjectID:=tempObjectID) _
  2197.     Then
  2198. '>>    If Not IsMissing(ObjectID) Then
  2199. '        Err = 0
  2200.         Set Item = _
  2201.             pvtCollection.Item _
  2202.                 (ObjectManager.pvtConvertToLongOrLeaveAlone _
  2203.                     (tempObjectID))
  2204. '>>        If Err = 5 Then
  2205. '            Set Item = Nothing
  2206. '            Exit Function
  2207. '        End If
  2208.     Else
  2209.         Set Item = Me
  2210.     End If
  2211. End Function
  2212.  
  2213.  
  2214. Public Property Get pvtListBoxSelectObject(ListBox As Variant) As Variant
  2215. ' Returns the selected object from the ListBox
  2216. ' Note:  this method should be coded as follows:
  2217. '       Dim MyDesiredObject As MyClass
  2218. '       Set MyDesiredObject = _
  2219. '           MyVBOFCollection.pvtListBoxSelectObject _
  2220. '               (MyListBox)
  2221.  
  2222.     Dim tempIndex As Long
  2223.     Dim tempObject As Object
  2224.     Dim tempCollection As Collection
  2225.  
  2226.     On Local Error Resume Next
  2227.     
  2228. ' bullet-proofing
  2229.     If IsMissing(ListBox) Then
  2230.         If pvtListBox Is Nothing Then
  2231.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxSelectObject' method for this object because the 'ListBox' or 'Collection' parameter is missing."
  2232.             Set pvtListBoxSelectObject = Nothing
  2233.             Exit Property
  2234.         End If
  2235.     Else
  2236.         Set pvtListBox = ListBox
  2237.     End If
  2238.  
  2239.     Set tempCollection = _
  2240.         pvtListBoxSelectedObjects(pvtListBox)
  2241.         
  2242.     If tempCollection.Count >= 1 Then
  2243.         Set pvtListBoxSelectObject = _
  2244.             tempCollection.Item(1)
  2245.     Else
  2246.         Set pvtListBoxSelectObject = _
  2247.             Nothing
  2248.     End If
  2249.  
  2250.     Set tempObject = Nothing
  2251. End Property
  2252.  
  2253. Public Property Set pvtListBoxSelectObject(ListBox As Variant, Object As Variant)
  2254. ' Selects the specified Object from the ListBox
  2255. ' Note:  this method should be coded as follows:
  2256. '       Dim MyDesiredObject As MyClass
  2257. '       MyVBOFCollection.pvtListBoxSelectObject _
  2258. '               (MyListBox) = MyDesiredObject
  2259.  
  2260.     Dim tempIndex As Long
  2261.     
  2262. ' bullet-proofing
  2263.     If IsMissing(ListBox) Or IsMissing(Object) Then
  2264.         If pvtListBox Is Nothing Then
  2265.             pvtErrorMessage TypeName(Me) & " cannot process the '.pvtListBoxSelectObject' method for this object because the 'ListBox' or 'Object' parameter is missing."
  2266.             Exit Property
  2267.         End If
  2268.     Else
  2269.         Set pvtListBox = ListBox
  2270.     End If
  2271.  
  2272.     If Object Is Nothing Then
  2273.         Exit Property
  2274.     End If
  2275.  
  2276. ' find Object in the collection
  2277.     tempIndex = _
  2278.         CollectionIndex(Item:=Object)
  2279.             
  2280. ' handle 'Not Found'
  2281.     If tempIndex <= 0 Then
  2282.         Exit Property
  2283.     End If
  2284.  
  2285. ' select the corresponding ListBox item
  2286.     pvtListBox.Selected(tempIndex - 1) = True
  2287.     
  2288. End Property
  2289.  
  2290.  
  2291.  
  2292. Public Property Set ObjectManager(anObjectManager As VBOFObjectManager)
  2293. ' Set my reference to the VBOFObjectManager
  2294. '   and register for Collection Events
  2295.     
  2296.     Set pvtVBOFObjectManager = anObjectManager
  2297.     
  2298. #If NoEventMgr = False Then
  2299.     pvtVBOFObjectManager. _
  2300.         RegisterForCollectionEvent _
  2301.         RegisterObject:=Me
  2302. #End If
  2303. End Property
  2304.  
  2305.  
  2306. Public Property Get Parent()
  2307. Attribute Parent.VB_Description = "Sets the Parent property"
  2308. ' Returns the most recently specified
  2309. '   Parent:= object
  2310.  
  2311.     Set Parent = pvtParent
  2312. End Property
  2313.  
  2314. Private Function pvtAddItemToCollection( _
  2315.     Optional Item As Variant, _
  2316.     Optional Key As Variant, _
  2317.     Optional After As Variant) As Collection
  2318. ' Return the VBOFCollection after having added
  2319. '   Item.  Take into account the impact of the
  2320. '   After parameter
  2321.  
  2322.     Dim tempAfter As Long
  2323.     Dim tempCollectionIndex As Long
  2324.     Dim tempAfterVariant As Variant
  2325.     
  2326.     On Local Error Resume Next
  2327.     
  2328. ' use any specified After value
  2329.     tempAfter = pvtCollection.Count
  2330.     If Not IsMissing(After) Then
  2331.         If InStr("Long Integer", TypeName(After)) <> 0 Then
  2332.             If After <= pvtCollection.Count Then
  2333.                 tempAfter = After
  2334.             End If
  2335.         Else
  2336.             tempAfter = _
  2337.                 CollectionIndex(Item:=After)
  2338.         End If
  2339.     End If
  2340.     
  2341. ' insert somewhere after the first item
  2342.     If tempAfter > 0 Then
  2343.         pvtCollection.Add _
  2344.             Item:=Item, _
  2345.             Key:=CStr(Item.ObjectID), _
  2346.             After:=tempAfter
  2347.             
  2348. ' insert before the first item
  2349.     ElseIf pvtCollection.Count > 0 Then
  2350.         pvtCollection.Add _
  2351.             Item:=Item, _
  2352.             Key:=CStr(Item.ObjectID), _
  2353.             Before:=1
  2354.             
  2355. ' insert as the first item
  2356.     Else
  2357.         pvtCollection.Add _
  2358.             Item:=Item, _
  2359.             Key:=CStr(Item.ObjectID)
  2360.     End If
  2361.  
  2362. ' add the reference to the pvtDBGridBookmarkArray
  2363.     If Err = 0 Then
  2364.         pvtAddItemToDBGridArray _
  2365.             Item:=Item
  2366.     End If
  2367.  
  2368.     Set pvtAddItemToCollection = _
  2369.         pvtCollection
  2370. End Function
  2371.  
  2372. Private Sub pvtAddItemToDBGridArray(Optional Item As Variant, Optional Collection As Variant)
  2373. ' Add the Item to the pvtDBGridBookmarkArray
  2374.  
  2375.     Dim tempCollectionIndex As Long
  2376.  
  2377.     tempCollectionIndex = _
  2378.         CollectionIndex( _
  2379.             Item:=Item, _
  2380.             Collection:=Collection)
  2381.             
  2382.     If tempCollectionIndex > 0 Then
  2383.         pvtDBGridBookmarkArrayAdd _
  2384.             tempCollectionIndex - 1, _
  2385.             tempCollectionIndex - 1, _
  2386.             CStr(Item.ObjectID)
  2387.     End If
  2388. 'DebugpvtDBGridBookmarkArray
  2389. End Sub
  2390.  
  2391. Private Function pvtBuildSQLStatementFromWhereClause(Optional WhereClause As Variant) As String
  2392. Attribute pvtBuildSQLStatementFromWhereClause.VB_Description = "(Private) returns an SQL Select statement which includes a user-specified Where clause.  The SQL statement should be appropriate for retrieving all of the items contained within the specified parent object"
  2393. ' Return an SQL Statement which uses WhereClause to
  2394. '   select the desired rows
  2395.     
  2396.     Dim SQLStatement As String
  2397.     
  2398.     On Local Error Resume Next
  2399.     
  2400. ' ask the Sample for certain critical services
  2401.     pvtSampleTableName = pvtSample.ObjectDataSource
  2402.     If Err = pvtReceiverDoesNotSupportThisMethod Then
  2403.         pvtErrorMessage "Class Module '" & TypeName(pvtSample) & "' does not support the method 'TableName'." & vbCrLf & "Object cannot be supported by " & TypeName(Me) & " without this method."
  2404.     End If
  2405.  
  2406.     pvtSampleType = TypeName(pvtSample)
  2407. '    If Err = pvtReceiverDoesNotSupportThisMethod Then
  2408. '        pvtErrorMessage "Class Module '" & TypeName(pvtSample) & "' does not support the method 'ObjectType'." & vbCrLf & "Object cannot be supported by " & TypeName(Me) & " without this method."
  2409. '    End If
  2410.     
  2411.     On Local Error Resume Next
  2412.     
  2413.     SQLStatement = _
  2414.         "SELECT DISTINCTROW " & _
  2415.         pvtSampleTableName & ".* FROM " & _
  2416.         pvtSampleTableName & " WHERE " & _
  2417.         WhereClause
  2418.     SQLStatement = SQLStatement & _
  2419.         pvtConcatenateOrderByClause( _
  2420.             SQL:=SQLStatement, _
  2421.             OrderByClause:=pvtOrderByClause)
  2422.        
  2423.     pvtBuildSQLStatementFromWhereClause = SQLStatement
  2424. End Function
  2425.  
  2426.  
  2427. Private Function pvtBuildSQLStatementFromParent(Optional Parent As Variant) As String
  2428. Attribute pvtBuildSQLStatementFromParent.VB_Description = "(Private) returns an SQL Select statement which can be used to retrieve all of the items contained within the specified parent object"
  2429. ' Returns an SQL Statement which retrieves rows
  2430. '   of the child table based on the value of
  2431. '   the Parent object.  If a WhereClause has been
  2432. '   specified, it is appended to the end of the
  2433. '   standard SQL statement for object containment.
  2434.     
  2435.     Dim SQLStatement As String
  2436.     
  2437.     If Not pvtSetParent( _
  2438.             Parent:=Parent, _
  2439.             MethodName:="pvtBuildSQLStatementFromParent") Then
  2440.         pvtBuildSQLStatementFromParent = ""
  2441.         Exit Function
  2442.     End If
  2443.     
  2444.     SQLStatement = _
  2445.         pvtBuildSQLStatementFromParentCode( _
  2446.             Sample:=pvtSample, _
  2447.             Parent:=pvtParent)
  2448.     
  2449. ' concatenate the supplemental Where Clause
  2450.     If pvtWhereClause <> "" Then
  2451.         SQLStatement = SQLStatement & _
  2452.             " AND " & pvtWhereClause
  2453.     End If
  2454.     
  2455. ' concatenate the OrderBy Clause
  2456.     SQLStatement = SQLStatement & _
  2457.         pvtConcatenateOrderByClause( _
  2458.             SQL:=SQLStatement, _
  2459.             OrderByClause:=pvtOrderByClause)
  2460.        
  2461.     pvtBuildSQLStatementFromParent = SQLStatement
  2462. End Function
  2463.  
  2464. Private Function pvtBuildSQLStatementFromParentCode(Optional Parent As Variant, Optional Sample As Variant) As String
  2465. ' Returns an SQL Statement which retrieves rows
  2466. '   of the child table based on the value of
  2467. '   the Parent object.  If a WhereClause has been
  2468. '   specified, it is appended to the end of the
  2469. '   standard SQL statement for object containment.
  2470.     
  2471.     Dim SQLStatement As String
  2472.         
  2473.     On Local Error Resume Next
  2474.     
  2475. ' ask the Sample for certain critical services
  2476.     pvtSampleTableName = _
  2477.         Sample.ObjectDataSource
  2478.     pvtSampleType = _
  2479.         TypeName(Sample)
  2480.     pvtParentTableName = _
  2481.         Parent.ObjectDataSource
  2482.     pvtParentType = _
  2483.         TypeName(Parent)
  2484.     
  2485. ' (SQL Statement modeled in MS Access)
  2486. 'SELECT DISTINCTROW
  2487. '       Persons.* FROM (VBObjectFrameworkObjectLinks INNER JOIN
  2488. '       Company ON VBObjectFrameworkObjectLinks.FromObjectID =
  2489. '       Company.ObjectID) INNER JOIN
  2490. '       Persons ON VBObjectFrameworkObjectLinks.ToObjectID =
  2491. '       Persons.ObjectID WHERE ((VBObjectFrameworkObjectLinks.FromObjectType="
  2492. '       Company") AND (VBObjectFrameworkObjectLinks.ToObjectType="
  2493. '       Person") AND (
  2494. '       Company.ObjectID=
  2495. '       1));
  2496.     If Not pvtANSISQL Then
  2497.         SQLStatement = _
  2498.             "SELECT DISTINCTROW " & _
  2499.             pvtSampleTableName & ".* FROM (" & ObjectDataSource() & " INNER JOIN " & _
  2500.             pvtParentTableName & " ON " & ObjectDataSource() & ".FromObjectID = " & _
  2501.             pvtParentTableName & ".ObjectID) INNER JOIN " & _
  2502.             pvtSampleTableName & " ON " & ObjectDataSource() & ".ToObjectID = " & _
  2503.             pvtSampleTableName & ".ObjectID WHERE ((" & ObjectDataSource() & ".FromObjectType='"
  2504.         SQLStatement = SQLStatement & _
  2505.             pvtParentType & "') AND (" & ObjectDataSource() & ".ToObjectType='" & _
  2506.             pvtSampleType & "') AND (" & _
  2507.             pvtParentTableName & ".ObjectID=" & _
  2508.             CStr(Parent.ObjectID) & "))"
  2509.     Else
  2510.         SQLStatement = _
  2511.             "SELECT " & _
  2512.             pvtSampleTableName & ".* FROM " & _
  2513.             pvtSampleTableName & ", " & _
  2514.             pvtParentTableName & ", " & _
  2515.             ObjectDataSource() & " "
  2516.         SQLStatement = SQLStatement & _
  2517.             "WHERE " & _
  2518.             ObjectDataSource() & ".FromObjectID = " & _
  2519.             pvtParentTableName & ".ObjectID AND " & _
  2520.             ObjectDataSource() & ".ToObjectID = " & _
  2521.             pvtSampleTableName & ".ObjectID "
  2522.         SQLStatement = SQLStatement & _
  2523.             "AND " & _
  2524.             ObjectDataSource() & ".FromObjectType='" & _
  2525.             pvtParentType & "' AND " & ObjectDataSource() & ".ToObjectType='" & _
  2526.             pvtSampleType & "' AND " & _
  2527.             pvtParentTableName & ".ObjectID=" & _
  2528.             CStr(Parent.ObjectID)
  2529.     End If
  2530.        
  2531.     pvtBuildSQLStatementFromParentCode = SQLStatement
  2532. End Function
  2533.  
  2534.  
  2535. Private Sub pvtDBGridBookmarkArrayAdd(RowIndex As Long, Bookmark As Variant, ObjectID As Variant)
  2536. ' Adds an Object / DBGrid Row cross-reference element
  2537.     
  2538.     Dim tempMaxIndex As Long
  2539.     Dim I As Long
  2540.     
  2541.     On Local Error GoTo pvtDBGridBookmarkArrayAdd_Exit
  2542.     
  2543.     tempMaxIndex = UBound(pvtDBGridBookmarkArray, 2)
  2544.     
  2545. ' if adding the new RowIndex at the end
  2546.     If RowIndex > tempMaxIndex _
  2547.     Or Not pvtDBGridBookmarkArrayAvailable Then
  2548.         ReDim Preserve _
  2549.             pvtDBGridBookmarkArray( _
  2550.                 1 To 2, _
  2551.                 0 To RowIndex)
  2552.  
  2553. ' if adding somewhere in the middle
  2554.     Else
  2555.         ReDim Preserve _
  2556.             pvtDBGridBookmarkArray( _
  2557.                 1 To 2, _
  2558.                 0 To tempMaxIndex + 1)
  2559.     End If
  2560.  
  2561. ' up-shift the lower-position entries
  2562.     For I = UBound(pvtDBGridBookmarkArray, 2) - 1 _
  2563.     To RowIndex Step -1
  2564.         pvtDBGridBookmarkArray(1, I + 1) = _
  2565.             pvtDBGridBookmarkArray(1, I)
  2566.         
  2567.         pvtDBGridBookmarkArray(2, I + 1) = _
  2568.             pvtDBGridBookmarkArray(2, I)
  2569.     Next I
  2570.         
  2571.     pvtDBGridBookmarkArrayAvailable = True
  2572.     
  2573.     pvtDBGridBookmarkArray(1, RowIndex) = CStr(Bookmark)
  2574.     pvtDBGridBookmarkArray(2, RowIndex) = ObjectID
  2575. pvtDBGridBookmarkArrayAdd_Exit:
  2576.     Exit Sub
  2577. End Sub
  2578.  
  2579.  
  2580. Private Sub pvtDBGridBookmarkArrayDeleteBookmark(Bookmark As Variant)
  2581.  
  2582.     Dim tempRowIndex As Long
  2583.  
  2584.     tempRowIndex = _
  2585.         pvtDBGridRowIndexAtBookmark(Bookmark)
  2586.  
  2587.     If tempRowIndex >= 0 Then
  2588.         pvtDBGridBookmarkArrayDeleteRowIndex _
  2589.           (tempRowIndex)
  2590.     End If
  2591.  
  2592. End Sub
  2593.  
  2594. Private Sub pvtDBGridBookmarkArrayDeleteRowIndex(RowIndex As Long)
  2595. ' Deletes an Object / DBGrid Row cross-reference
  2596. '   element by its RowIndex
  2597.  
  2598.     Dim I As Long
  2599.     
  2600.     For I = RowIndex To _
  2601.     UBound(pvtDBGridBookmarkArray, 2) - 1
  2602.         pvtDBGridBookmarkArray(1, I) = _
  2603.             pvtDBGridBookmarkArray(1, I + 1)
  2604.     
  2605.         pvtDBGridBookmarkArray(2, I) = _
  2606.             pvtDBGridBookmarkArray(2, I + 1)
  2607.     Next I
  2608.  
  2609.     ReDim Preserve pvtDBGridBookmarkArray( _
  2610.         1 To 2, _
  2611.         0 To UBound(pvtDBGridBookmarkArray, 2) - 1)
  2612. End Sub
  2613.  
  2614.  
  2615.  
  2616.  
  2617. Private Function pvtDBGridBookmarkAtRowIndex(RowIndex As Long) As Variant
  2618.  
  2619.     pvtDBGridBookmarkAtRowIndex = _
  2620.         pvtDBGridBookmarkArray _
  2621.                     (1, RowIndex)
  2622. End Function
  2623.  
  2624.  
  2625. Private Function pvtDBGridObjectIDAtBookmark(Bookmark As Variant) As Variant
  2626.  
  2627.     On Local Error GoTo pvtDBGridObjectIDAtBookmark_Error
  2628.  
  2629.     pvtDBGridObjectIDAtBookmark = _
  2630.         pvtDBGridBookmarkArray( _
  2631.             2, _
  2632.             pvtDBGridRowIndexAtBookmark(Bookmark))
  2633.  
  2634. pvtDBGridObjectIDAtBookmark_Error:
  2635.     Exit Function
  2636. End Function
  2637.  
  2638.  
  2639.  
  2640. Private Function pvtDBGridObjectIDAtRowIndex(RowIndex As Long) As Variant
  2641.  
  2642.     pvtDBGridObjectIDAtRowIndex = _
  2643.         pvtDBGridBookmarkArray _
  2644.                     (2, RowIndex)
  2645. End Function
  2646.  
  2647.  
  2648. Private Function pvtDBGridRowIndexAtBookmark(Bookmark As Variant) As Long
  2649.  
  2650.     On Local Error GoTo pvtDBGridRowIndexAtBookmark_Error
  2651.  
  2652.     Dim I As Long
  2653.     
  2654.     For I = 0 _
  2655.     To UBound(pvtDBGridBookmarkArray, 2)
  2656.         If pvtDBGridBookmarkArray(1, I) = Bookmark Then
  2657.             pvtDBGridRowIndexAtBookmark = I
  2658.             Exit Function
  2659.         End If
  2660.     Next I
  2661.  
  2662. pvtDBGridRowIndexAtBookmark_Error:
  2663.     pvtDBGridRowIndexAtBookmark = -1
  2664.     Exit Function
  2665. End Function
  2666.  
  2667.  
  2668. Private Function pvtDBGridRowIndexAtObjectID(ObjectID As Variant) As Long
  2669.  
  2670.     Dim I As Long
  2671.     
  2672.     For I = 0 _
  2673.     To UBound(pvtDBGridBookmarkArray, 2)
  2674.         If pvtDBGridBookmarkArray(2, I) = ObjectID Then
  2675.             pvtDBGridRowIndexAtObjectID = I
  2676.             Exit Function
  2677.         End If
  2678.     Next I
  2679.  
  2680.     pvtDBGridRowIndexAtObjectID = -1
  2681. End Function
  2682.  
  2683.  
  2684. Private Function pvtDBGridGetRelativeBookmark(Bookmark As Variant, Increment As Long, MaxRow As Long) As Variant
  2685.  
  2686.     Dim I As Long
  2687.     
  2688.     I = pvtDBGridIndexFromBookmark _
  2689.             (Bookmark, False, MaxRow) + _
  2690.             Increment
  2691.     If I < 0 Or I >= MaxRow Then
  2692.         pvtDBGridGetRelativeBookmark = Null
  2693.     Else
  2694.         pvtDBGridGetRelativeBookmark = _
  2695.             pvtDBGridMakeBookmark(I)
  2696.     End If
  2697.  
  2698. End Function
  2699.  
  2700. Private Function pvtDBGridIndexFromBookmark(Bookmark As Variant, ReadPriorRows As Boolean, MaxRow As Long) As Long
  2701.  
  2702.     Dim I As Long
  2703.  
  2704.     If IsNull(Bookmark) Then
  2705.         If ReadPriorRows Then
  2706.             pvtDBGridIndexFromBookmark = MaxRow
  2707.         Else
  2708.             pvtDBGridIndexFromBookmark = -1
  2709.         End If
  2710.     Else
  2711.         I = Val(Bookmark)
  2712.         
  2713.         If I < 0 Or I >= MaxRow Then
  2714.             I = -MaxRow
  2715.         End If
  2716.         
  2717.         pvtDBGridIndexFromBookmark = I
  2718.     End If
  2719.  
  2720. End Function
  2721.  
  2722. Private Function pvtDBGridMakeBookmark(Index As Long) As Variant
  2723.     pvtDBGridMakeBookmark = CStr(Index)
  2724. End Function
  2725.  
  2726.  
  2727. Private Function pvtDBGridObjectAtRowIndex(RowIndex As Long) As Variant
  2728. ' Returns the Object which occupies the row in the
  2729. '   DBGrid specified by RowIndex
  2730.  
  2731.     pvtDBGridObjectAtRowIndex = _
  2732.         pvtCollection.Item _
  2733.             (CollectionIndex _
  2734.                 (Key:=CStr(pvtDBGridBookmarkArray _
  2735.                     (2, RowIndex))))
  2736.  
  2737. End Function
  2738.  
  2739.  
  2740. Private Function pvtIsCollectionInstantiated() As Long
  2741. Attribute pvtIsCollectionInstantiated.VB_Description = "(Private) internal function"
  2742. ' Verify that the pvtCollection has been
  2743. '   instantiated
  2744.  
  2745.     If pvtCollection Is Nothing Then
  2746.         pvtErrorMessage TypeName(Me) & " cannot provide meaningfuly functionality because the collection has not been built."
  2747.         pvtIsCollectionInstantiated = False
  2748.         Exit Function
  2749.     End If
  2750.  
  2751.     pvtIsCollectionInstantiated = True
  2752. End Function
  2753.  
  2754. Private Function pvtIsRecordSetInitialized() As Long
  2755. Attribute pvtIsRecordSetInitialized.VB_Description = "(Private) internal function"
  2756. ' Verify that the RecordSet has been initialized
  2757.  
  2758.     If pvtRecordSet Is Nothing Then
  2759.         pvtErrorMessage TypeName(Me) & " cannot insert data into the database because the collection was never built."
  2760.         pvtIsRecordSetInitialized = False
  2761.         Exit Function
  2762.     End If
  2763.  
  2764.     pvtIsRecordSetInitialized = True
  2765. End Function
  2766.  
  2767. Private Function pvtIsSQLAccessable() As Long
  2768. Attribute pvtIsSQLAccessable.VB_Description = "(Private) internal function"
  2769. ' Determine whether or not the desired table data
  2770. '   can be derived, given the information provided
  2771.     
  2772.     If (pvtParent Is Nothing _
  2773.     And pvtWhereClause = "" _
  2774.     And pvtSQLStatement = "" _
  2775.     ) Then
  2776.         pvtErrorMessage TypeName(Me) & " cannot perform object instantiations without having been provided with either an SQL:=, a WhereClause:= or a Parent:= ."
  2777.         pvtIsSQLAccessable = False
  2778.         Exit Function
  2779.     End If
  2780.  
  2781.     pvtIsSQLAccessable = True
  2782. End Function
  2783.  
  2784.  
  2785. Public Property Get Collection() As Collection
  2786. Attribute Collection.VB_Description = "Returns the underlying VB Collection"
  2787. ' Returns the underlying Collection object
  2788.  
  2789.     Set Collection = pvtCollection
  2790. End Property
  2791.  
  2792. Private Function pvtConcatenateOrderByClause(Optional SQL As Variant, Optional OrderByClause As Variant) As String
  2793. ' Return either a null string or an OrderBy clause
  2794. '   including the leading "Order By"
  2795.  
  2796.     If OrderByClause <> "" Then
  2797.         pvtConcatenateOrderByClause = _
  2798.             " ORDER BY " & _
  2799.             OrderByClause
  2800.     Else
  2801.         pvtConcatenateOrderByClause = ""
  2802.     End If
  2803.  
  2804. End Function
  2805.  
  2806.  
  2807. Private Function pvtCreateSQLStatement() As String
  2808. Attribute pvtCreateSQLStatement.VB_Description = "(Private) internal function"
  2809. ' Evaluate the available information and create
  2810. '   an SQL Statement to access the desired rows
  2811.  
  2812. ' decide how to acquire an SQL Statement:
  2813. '   first try the SQL Statement variable
  2814.     If pvtSQLStatement = "" Then
  2815.             pvtSQLStatement = _
  2816.                 pvtBuildSQLStatementFromParent( _
  2817.                     Parent:=pvtParent)
  2818.     End If
  2819.  
  2820.     pvtCreateSQLStatement = pvtSQLStatement
  2821. End Function
  2822.  
  2823. Private Function pvtDBInsert(Optional Item As Variant) As Long
  2824. Attribute pvtDBInsert.VB_Description = "(Private) inserts the item from the associated table"
  2825. ' Insert Item into the table, then return
  2826. '   its ObjectID value
  2827.  
  2828.     Dim tempObjectErr As Long
  2829.     Dim tempBookmark As String
  2830.  
  2831.     On Local Error Resume Next
  2832.     
  2833.     If Not pvtIsRecordSetInitialized() Then
  2834.         pvtDBInsert = False
  2835.         Exit Function
  2836.     End If
  2837.     
  2838. ' prepare a new record area
  2839.     pvtRecordSet.AddNew
  2840.  
  2841. ' have the Item populate the RecordSet.
  2842. '   check for errors on that end
  2843.     Err = 0
  2844.     tempObjectErr = _
  2845.         Item.ObjectInitializeRecordSet(pvtRecordSet)
  2846.     If tempObjectErr <> 0 _
  2847.     Or Err <> 0 Then
  2848.         If Err = pvtReceiverDoesNotSupportThisMethod Or tempObjectErr = pvtReceiverDoesNotSupportThisMethod Then
  2849.             pvtErrorMessage "Class Module '" & TypeName(Item) & "' does not support the method 'InitializeRecordSet'." & vbCrLf & "Object cannot be supported by " & TypeName(Me) & " without this method."
  2850.         End If
  2851.         
  2852.         pvtDBInsert = 0
  2853.         Exit Function
  2854.     End If
  2855.  
  2856. ' execute the update
  2857.     pvtRecordSet.Update
  2858.  
  2859. ' Note: the following "If" line is commented because
  2860. '   it is possible for Err to be contanimated by the
  2861. '   application if it is using this RecordSet, say
  2862. '   attached to a DataControl with a Reposition
  2863. '   event coded.
  2864. ' return the ObjectID
  2865. '    If Err = 0 Then
  2866.         tempBookmark = pvtRecordSet.LastModified
  2867.         pvtRecordSet.Bookmark = tempBookmark
  2868. '    End If
  2869.     
  2870.     pvtDBInsert = pvtRecordSet("ObjectID")
  2871. End Function
  2872.  
  2873.  
  2874. Private Function pvtErrorMessage(Optional ErrorMessage As Variant) As Long
  2875. Attribute pvtErrorMessage.VB_Description = "(Private) internal function"
  2876.     pvtErrorMessage = _
  2877.         pvtVBOFObjectManager.DisplayErrorMessage _
  2878.             (ErrorMessage)
  2879. End Function
  2880.  
  2881.  
  2882. Public Property Get ObjectManager() As VBOFObjectManager
  2883. ' Return my reference to the VBOFObjectManager
  2884.     
  2885.     Set ObjectManager = pvtVBOFObjectManager
  2886. End Property
  2887.  
  2888.  
  2889. Private Function pvtDBSelect(Optional SQL As Variant) As RecordSet
  2890. Attribute pvtDBSelect.VB_Description = "(Private) selects the contained items from the associated table"
  2891. ' Process the SQL Select statement and return
  2892. '   a RecordSet
  2893.  
  2894. ' open a RecordSet containing the desired rows
  2895.     Set pvtDBSelect = _
  2896.         pvtDatabase. _
  2897.             OpenRecordset( _
  2898.                 SQL, _
  2899.                 dbOpenDynaset, pvtODBCPassThrough)
  2900.     
  2901.     pvtDBHasBeenReferenced = True
  2902. End Function
  2903.  
  2904. Private Function pvtDBUpdate(Optional Item As Variant) As VBOFCollection
  2905. Attribute pvtDBUpdate.VB_Description = "(Private) updates the item from the associated table"
  2906. ' Update the Item in the table
  2907.  
  2908.     On Local Error Resume Next
  2909.     
  2910.     If pvtRecordSet Is Nothing Then
  2911.         pvtErrorMessage TypeName(Me) & " cannot update data in the database because the collection was never built."
  2912.         Set pvtDBUpdate = Nothing
  2913.         Exit Function
  2914.     End If
  2915.     
  2916. ' prepare a new record area
  2917.     pvtRecordSet.Edit
  2918.  
  2919. ' have the Item populate the RecordSet
  2920.     Item.ObjectInitializeRecordSet (pvtRecordSet)
  2921.     If Err = pvtReceiverDoesNotSupportThisMethod Then
  2922.         pvtErrorMessage "Class Module '" & TypeName(Item) & "' does not support the method 'InitializeRecordSet'." & vbCrLf & "Object cannot be supported by " & TypeName(Me) & " without this method."
  2923.     End If
  2924.     
  2925. ' execute the update
  2926.     pvtRecordSet.Update
  2927.  
  2928. ' return the colection
  2929.     Set pvtDBUpdate = Me
  2930. End Function
  2931.  
  2932. Private Function pvtDBDelete() As Long
  2933. Attribute pvtDBDelete.VB_Description = "(Private) deletes the item from the associated table"
  2934. ' Delete the current row of the RecordSet
  2935.  
  2936.     On Local Error Resume Next
  2937.     
  2938. ' bullet-proofing
  2939.     If pvtRecordSet Is Nothing Then
  2940.         pvtErrorMessage TypeName(Me) & " cannot delete data in the database because the collection was never built."
  2941.         pvtDBDelete = False
  2942.         Exit Function
  2943.     End If
  2944.         
  2945. ' delete the record
  2946.     Err = 0
  2947.     pvtRecordSet.Delete
  2948.  
  2949.     If Err = 0 Then
  2950.         pvtDBDelete = True
  2951.     Else
  2952.         pvtDBDelete = False
  2953.     End If
  2954. End Function
  2955.  
  2956.  
  2957. Private Function pvtInstantiateObjectsFromRecordSet(Optional RecordSet As Variant, Optional Collection) As Collection
  2958. ' Return a Collection of objects which have been
  2959. '   instantiated from data found in RecordSet
  2960.     
  2961.     Dim tempRow As Object
  2962.     Dim newChildObject As Object
  2963.     Dim tempIndex As Long
  2964.     Dim tempCollection As New Collection
  2965.  
  2966.     On Local Error Resume Next
  2967.  
  2968. ' clear the pvtDBGridBookmarkArray
  2969.     pvtDBGridBookmarkArrayClear
  2970.     
  2971. ' process the RecordSet
  2972.     While Not RecordSet.EOF
  2973.     
  2974. ' determine whether or not the retrieved row
  2975. '   has an instantiated object already in the
  2976. '   VBOFCollection
  2977.         tempIndex = _
  2978.             CollectionIndex( _
  2979.                 Item:=CStr(RecordSet("ObjectID")))
  2980.         If tempIndex > 0 Then
  2981.             Set newChildObject = _
  2982.                 pvtCollection(tempIndex)
  2983.         
  2984. ' else, must instantiate a new object of the class
  2985.         Else
  2986.         
  2987. ' have the Sample Object return an instantiated
  2988. '   copy of itself
  2989.             Set newChildObject = _
  2990.                 ObjectManager. _
  2991.                     pvtInstantiateNewObjectFromSample _
  2992.                         (Sample:=pvtSample)
  2993.             If newChildObject Is Nothing Then
  2994.                 GoTo pvtInstantiateObjectsFromRecordSet_Error
  2995.             End If
  2996.         End If
  2997.  
  2998. ' have the new instantiated object copy populate
  2999. '   itself from this RecordSet row
  3000.         Set newChildObject = _
  3001.             ObjectManager. _
  3002.                 pvtObjectInitializeFromRecordSet( _
  3003.                     Object:=newChildObject, _
  3004.                     RecordSet:=RecordSet)
  3005.         If newChildObject Is Nothing Then
  3006.             GoTo pvtInstantiateObjectsFromRecordSet_Exit
  3007.         End If
  3008.         
  3009. ' add the object to the collection
  3010. '   (if it is unique)
  3011.         pvtAddUniqueItemToCollection _
  3012.             Item:=newChildObject, _
  3013.             Parent:=Me, _
  3014.             Collection:=tempCollection
  3015.         
  3016.         RecordSet.MoveNext
  3017.     Wend
  3018.         
  3019.     GoTo pvtInstantiateObjectsFromRecordSet_Exit
  3020.  
  3021. pvtInstantiateObjectsFromRecordSet_Error:
  3022.     
  3023. pvtInstantiateObjectsFromRecordSet_Exit:
  3024.     Set pvtInstantiateObjectsFromRecordSet = _
  3025.         tempCollection
  3026.     Set tempRow = Nothing
  3027.     Set newChildObject = Nothing
  3028. End Function
  3029. Private Function pvtIsDatabaseSpecified() As Integer
  3030. Attribute pvtIsDatabaseSpecified.VB_Description = "(Private) internal function"
  3031. ' Determine whether or not the database has been
  3032. '   specified
  3033.  
  3034.     If pvtDatabase Is Nothing Then
  3035.         pvtErrorMessage TypeName(Me) & " cannot function without having been provided the name of the database.  Use the 'Database:=' parameter of the pvtPopulateFromDatabase method to specify the database."
  3036.         pvtIsDatabaseSpecified = False
  3037.         Exit Function
  3038.     End If
  3039.  
  3040.     pvtIsDatabaseSpecified = True
  3041. End Function
  3042.  
  3043. Private Function pvtSetParent(Optional Parent As Variant, Optional MethodName As Variant) As Boolean
  3044.     
  3045.     On Local Error Resume Next
  3046.     
  3047.     pvtSetParent = True
  3048.     
  3049.     If IsMissing(Parent) Then
  3050.         If pvtParent Is Nothing Then
  3051.             pvtErrorMessage TypeName(Me) & " cannot process the '." & MethodName & "' method for this object because the 'Parent:=' parameter is missing and no preceeding method has established a default object."
  3052.             pvtSetParent = False
  3053.         End If
  3054.     ElseIf Not Parent Is Nothing Then
  3055.         Set pvtParent = Parent
  3056.     End If
  3057.  
  3058. End Function
  3059.  
  3060. Private Function pvtSetSample(Optional Sample As Variant, Optional MethodName As Variant) As Boolean
  3061.     
  3062.     On Local Error Resume Next
  3063.     
  3064.     pvtSetSample = True
  3065.     
  3066.     If IsMissing(Sample) Then
  3067.         If pvtSample Is Nothing Then
  3068.             pvtErrorMessage TypeName(Me) & " cannot process the '." & MethodName & "' method for this object because the 'Sample' parameter is missing and no preceeding method has established a default."
  3069.             pvtSetSample = False
  3070.         End If
  3071.     End If
  3072.  
  3073. End Function
  3074.  
  3075.  
  3076. Private Sub pvtReceiveGeneralParameters(Optional Database As Variant, Optional Sample As Variant, Optional Parent As Variant, Optional WhereClause As Variant, Optional SQL As Variant, Optional OrderByClause As Variant, Optional CollectionEmulationMode As Variant, Optional ANSISQL As Variant, Optional ODBCPassThrough As Variant)
  3077. Attribute pvtReceiveGeneralParameters.VB_Description = "(Private) internal function"
  3078. ' Receive user-defined parameters
  3079.  
  3080.     If Not IsMissing(Database) Then
  3081.         Set pvtDatabase = Database
  3082.         pvtCollectionEmulationMode = False
  3083.     End If
  3084.     
  3085.     If Not IsMissing(Sample) Then
  3086.         Set pvtSample = Sample
  3087.     End If
  3088.     
  3089.     If Not IsMissing(Parent) Then
  3090.         
  3091.         Set pvtParent = Parent
  3092.     End If
  3093.     
  3094.     If Not IsMissing(WhereClause) Then
  3095.         pvtWhereClause = WhereClause
  3096.         pvtCollectionEmulationMode = False
  3097.     End If
  3098.     
  3099.     If Not IsMissing(SQL) Then
  3100.         pvtSQLStatement = SQL
  3101.         pvtCollectionEmulationMode = False
  3102.         pvtSQLStatementProvidedByUser = True
  3103.     End If
  3104.     
  3105.     If Not IsMissing(OrderByClause) Then
  3106.         pvtOrderByClause = OrderByClause
  3107.         pvtCollectionEmulationMode = False
  3108.     End If
  3109.  
  3110.     If Not IsMissing(CollectionEmulationMode) Then
  3111.         pvtCollectionEmulationMode = CollectionEmulationMode
  3112.     End If
  3113.  
  3114.     If Not IsMissing(ANSISQL) Then
  3115.         pvtANSISQL = ANSISQL
  3116.     End If
  3117.     
  3118.     If Not IsMissing(ODBCPassThrough) Then
  3119.         If ODBCPassThrough Then
  3120.             pvtODBCPassThrough = dbSQLPassThrough
  3121.         Else
  3122.             pvtODBCPassThrough = 0
  3123.         End If
  3124.     End If
  3125. End Sub
  3126.  
  3127. Public Property Get pvtRecordSetAbsolutePosition() As Long
  3128. ' Gets the RecordSet's AbsolutePosition
  3129. '   property
  3130.  
  3131.     pvtRecordSetAbsolutePosition = _
  3132.         pvtRecordSet.AbsolutePosition
  3133. End Property
  3134.  
  3135. Public Property Let pvtRecordSetAbsolutePosition(RecordNumber As Long)
  3136. ' Sets the RecordSet's AbsolutePosition
  3137. '   property
  3138.  
  3139.     pvtRecordSet.AbsolutePosition = _
  3140.         RecordNumber
  3141. End Property
  3142.  
  3143. Public Function pvtRecordSetMoveFirst() As Variant
  3144. ' Moves the underlying RecordSet to the first record
  3145. '   and returns the object for that row
  3146.  
  3147.     Dim tempObject As Object
  3148.  
  3149.     On Local Error Resume Next
  3150.  
  3151.     pvtRecordSet.MoveFirst
  3152.  
  3153.     If pvtRecordSet.AbsolutePosition >= 0 Then
  3154.         Set pvtRecordSetMoveFirst = _
  3155.             Item(pvtRecordSet.AbsolutePosition + 1)
  3156.     Else
  3157.         Set pvtRecordSetMoveFirst = Nothing
  3158.     End If
  3159. End Function
  3160.  
  3161. Public Function pvtRecordSetFindFirst(Optional SearchCriteria As Variant) As Variant
  3162. ' Searches the underlying RecordSet for the first
  3163. '   record meeting the specified criteria
  3164. '   and returns the object for that row
  3165.  
  3166.     Dim tempObject As Object
  3167.  
  3168.     On Local Error Resume Next
  3169.  
  3170.     pvtRecordSet.FindFirst SearchCriteria
  3171.  
  3172.     If pvtRecordSet.AbsolutePosition >= 0 Then
  3173.         Set pvtRecordSetFindFirst = _
  3174.             Item(pvtRecordSet.AbsolutePosition + 1)
  3175.     Else
  3176.         Set pvtRecordSetFindFirst = Nothing
  3177.     End If
  3178. End Function
  3179.  
  3180. Public Function pvtRecordSetFindNext(Optional SearchCriteria As Variant) As Variant
  3181. ' Searches the underlying RecordSet for the next
  3182. '   record meeting the specified criteria
  3183. '   and returns the object for that row
  3184.  
  3185.     Dim tempObject As Object
  3186.  
  3187.     On Local Error Resume Next
  3188.  
  3189.     pvtRecordSet.FindNext SearchCriteria
  3190.  
  3191.     If pvtRecordSet.AbsolutePosition >= 0 Then
  3192.         Set pvtRecordSetFindNext = _
  3193.             Item(pvtRecordSet.AbsolutePosition + 1)
  3194.     Else
  3195.         Set pvtRecordSetFindNext = Nothing
  3196.     End If
  3197. End Function
  3198.  
  3199. Public Function pvtRecordSetFindPrevious(Optional SearchCriteria As Variant) As Variant
  3200. ' Searches the underlying RecordSet for the previous
  3201. '   record meeting the specified criteria
  3202. '   and returns the object for that row
  3203.  
  3204.     Dim tempObject As Object
  3205.  
  3206.     On Local Error Resume Next
  3207.  
  3208.     pvtRecordSet.FindPrevious SearchCriteria
  3209.  
  3210.     If pvtRecordSet.AbsolutePosition >= 0 Then
  3211.         Set pvtRecordSetFindPrevious = _
  3212.             Item(pvtRecordSet.AbsolutePosition + 1)
  3213.     Else
  3214.         Set pvtRecordSetFindPrevious = Nothing
  3215.     End If
  3216. End Function
  3217.  
  3218.  
  3219. Public Function pvtRecordSetFindLast(Optional SearchCriteria As Variant) As Variant
  3220. ' Searches the underlying RecordSet for the last
  3221. '   record meeting the specified criteria
  3222. '   and returns the object for that row
  3223.  
  3224.     Dim tempObject As Object
  3225.  
  3226.     On Local Error Resume Next
  3227.  
  3228.     pvtRecordSet.FindLast SearchCriteria
  3229.  
  3230.     If pvtRecordSet.AbsolutePosition >= 0 Then
  3231.         Set pvtRecordSetFindLast = _
  3232.             Item(pvtRecordSet.AbsolutePosition + 1)
  3233.     Else
  3234.         Set pvtRecordSetFindLast = Nothing
  3235.     End If
  3236. End Function
  3237.  
  3238.  
  3239.  
  3240. Public Function pvtRecordSetMoveLast() As Variant
  3241. ' Moves the underlying RecordSet to the last record
  3242. '   and returns the object for that row
  3243.  
  3244.     Dim tempObject As Object
  3245.  
  3246.     On Local Error Resume Next
  3247.  
  3248.     pvtRecordSet.MoveLast
  3249.  
  3250.     pvtRecordSetMoveLast = True
  3251.     
  3252.     If pvtRecordSet.AbsolutePosition >= 0 Then
  3253.         Set pvtRecordSetMoveLast = _
  3254.             Item(pvtRecordSet.AbsolutePosition + 1)
  3255.     Else
  3256.         Set pvtRecordSetMoveLast = Nothing
  3257.     End If
  3258. End Function
  3259.  
  3260. Public Function pvtRecordSetMoveToRecordNumber(Optional RecordNumber As Variant) As Variant
  3261. ' Moves the underlying RecordSet to the specified
  3262. '   record (by number) and returns the object for
  3263. '   that row
  3264.  
  3265.     Dim tempObject As Object
  3266.  
  3267.     On Local Error Resume Next
  3268.  
  3269. ' bullet-proofing
  3270.     If pvtRecordSet.RecordCount < RecordNumber Then
  3271.         Set pvtRecordSetMoveToRecordNumber = Nothing
  3272.         Exit Function
  3273.     End If
  3274.  
  3275.     pvtRecordSet.AbsolutePosition = _
  3276.         RecordNumber
  3277.     
  3278.     Set pvtRecordSetMoveToRecordNumber = _
  3279.         Item(pvtRecordSet.AbsolutePosition) ' ObjectID:=CStr(pvtRecordSet("ObjectID")))
  3280. End Function
  3281.  
  3282. Public Function pvtRecordSetPositionToItem(Optional Item As Variant, Optional Object As Variant) As Variant
  3283. ' Positions the underlying RecordSet to the
  3284. '   specifed Item and returns the Item
  3285.     
  3286.     Dim tempSpecifiedParameterObject As Object
  3287.     Dim tempParameterObjectWasSpecified As Boolean
  3288.  
  3289.     On Local Error Resume Next
  3290.     
  3291.     tempParameterObjectWasSpecified = _
  3292.         ObjectManager.pvtChooseObjectFromParameters( _
  3293.             Item:=Item, _
  3294.             Object:=Object, _
  3295.             ReturnObject:=tempSpecifiedParameterObject)
  3296.  
  3297.     Set pvtRecordSetPositionToItem = _
  3298.         pvtPositionRecordSetToItem _
  3299.             (Item:=tempSpecifiedParameterObject)
  3300. End Function
  3301.  
  3302.  
  3303. Public Function pvtRecordSetRefresh() As RecordSet
  3304. ' Pass thru to pvtRefreshRecordSet()
  3305.     
  3306.     Set pvtRecordSetRefresh = _
  3307.         pvtRefreshRecordSet()
  3308. End Function
  3309.  
  3310. Public Function pvtRecordSetBOF() As Boolean
  3311. ' Returns a boolean, based on whether or not the
  3312. ' underlying RecordSet is positioned at BOF
  3313.     
  3314.     On Local Error Resume Next
  3315.     
  3316.     pvtRecordSetBOF = _
  3317.         pvtRecordSet.BOF
  3318. End Function
  3319.  
  3320.  
  3321. Public Function pvtRecordSetRecordCount() As Long
  3322. ' Returns the RecordCount property of the
  3323. ' underlying RecordSet
  3324.     
  3325.     On Local Error Resume Next
  3326.     
  3327.     pvtRecordSetRecordCount = _
  3328.         pvtRecordSet.RecordCount
  3329. End Function
  3330.  
  3331. Public Function pvtRecordSetEOF() As Boolean
  3332. ' Returns a boolean, based on whether or not the
  3333. '   underlying RecordSet is positioned at EOF
  3334.     
  3335.     On Local Error Resume Next
  3336.     
  3337.     pvtRecordSetEOF = _
  3338.         pvtRecordSet.EOF
  3339. End Function
  3340.  
  3341.  
  3342. Public Function pvtRefreshRecordSet() As RecordSet
  3343. Attribute pvtRefreshRecordSet.VB_Description = "Refreshes the internally managed RecordSet which equates to the rows of the table which were used to instantiate the contained items.  Returns the RecordSet"
  3344. ' Return the refreshed RecordSet after having refreshed its
  3345. '   contents by again using the same SQL-oriented
  3346. '   information used previously to generate the current
  3347. '   VBOFCollection state.
  3348. ' Note: users of the method "pvtPopulateFromRecordSet"
  3349. '   should not use this method
  3350.  
  3351.     On Local Error Resume Next
  3352.  
  3353.     If pvtRecordSetProvidedByUser Then
  3354.         pvtErrorMessage TypeName(Me) & " cannot process the '.pvtRefreshRecordSet' method because the RecordSet used to instantiate the objects was provided by the user via the '.pvtPopulateFromRecordSet' method."
  3355.         Set Refresh = Me
  3356.     End If
  3357.  
  3358.     Refresh
  3359.     
  3360.     Set pvtRefreshRecordSet = pvtRecordSet
  3361. End Function
  3362.  
  3363.  
  3364. Public Sub SetDatabaseParameters( _
  3365.     Optional Database As Variant, _
  3366.     Optional Sample As Variant, _
  3367.     Optional Parent As Variant, _
  3368.     Optional WhereClause As Variant, _
  3369.     Optional SQL As Variant, _
  3370.     Optional OrderByClause As Variant, _
  3371.     Optional CollectionEmulationMode As Variant, _
  3372.     Optional ANSISQL As Variant, _
  3373.     Optional ODBCPassThrough As Variant)
  3374. ' Receive any database parameters the application
  3375. '   program wishes to set en masse.  As an
  3376. '   alternative, the application can provide
  3377. '   certain parameters for certain methods,
  3378. '   such as the .pvtPopulateFromRecordSet
  3379. '   and .pvtPopulateFromDatabase methods
  3380.  
  3381.     pvtReceiveGeneralParameters _
  3382.         Database:=Database, _
  3383.         Sample:=Sample, _
  3384.         Parent:=Parent, _
  3385.         WhereClause:=WhereClause, _
  3386.         OrderByClause:=OrderByClause, _
  3387.         SQL:=SQL, _
  3388.         CollectionEmulationMode:=CollectionEmulationMode, _
  3389.         ANSISQL:=ANSISQL, _
  3390.         ODBCPassThrough:=ODBCPassThrough
  3391.  
  3392. End Sub
  3393.  
  3394. Private Function pvtPopulateFromRecordSet(Optional RecordSet As Variant, Optional Database As Variant, Optional Sample As Variant, Optional Parent As Variant, Optional WhereClause As Variant, Optional SQL As Variant, Optional OrderByClause As Variant, Optional ANSISQL As Variant, Optional ODBCPassThrough As Variant) As VBOFCollection
  3395. Attribute pvtPopulateFromRecordSet.VB_Description = "Sets the internally managed RecordSet"
  3396. ' Sets a VBOFCollection object which has been
  3397. '   instantiated as a collection of objects
  3398. '   represented by the contents of RecordSet
  3399. ' Note: use of this method requires that the
  3400. '   caller maintain all of the necessary object
  3401. '   containment information, since VBOFCollection
  3402. '   is unaware of the techniques used to derive the
  3403. '   contents of RecordSet
  3404. '
  3405. ' Parameter Description:
  3406. '       see VBOFObjetManager.ManageCollection
  3407.     
  3408.     On Local Error Resume Next
  3409.  
  3410. ' bullet-proofing
  3411.     If IsMissing(RecordSet) Then
  3412.         pvtErrorMessage TypeName(Me) & " cannot process the '.pvtPopulateFromRecordSet' method because the 'RecordSet:=' parameter is mssing."
  3413.         Set pvtPopulateFromRecordSet = Nothing
  3414.     End If
  3415.  
  3416. ' test Sample for Database-readiness
  3417.     If Not IsMissing(Sample) Then
  3418.         If (Sample.ObjectDataSource = "" Or Err = 438) Then
  3419.             pvtCollectionEmulationMode = True
  3420.         End If
  3421.     End If
  3422.  
  3423.     pvtReceiveGeneralParameters _
  3424.         Database:=Database, _
  3425.         Sample:=Sample, _
  3426.         Parent:=Parent, _
  3427.         WhereClause:=WhereClause, _
  3428.         OrderByClause:=OrderByClause, _
  3429.         ANSISQL:=ANSISQL, _
  3430.         ODBCPassThrough:=ODBCPassThrough, _
  3431.         SQL:=SQL
  3432.  
  3433. ' reference the RecordSet containing the desired rows
  3434.     Set pvtRecordSet = RecordSet
  3435.  
  3436. ' create the objects from the contents of the RecordSet
  3437.     Set pvtCollection = _
  3438.         pvtInstantiateObjectsFromRecordSet( _
  3439.             RecordSet:=pvtRecordSet, _
  3440.             Collection:=pvtCollection)
  3441.     
  3442. #If NoDebugMode = False Then
  3443.     If pvtVBOFObjectManager.DebugMode Then
  3444.         pvtVBOFObjectManager.DisplayDebugMessage _
  3445.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has instantiated a collection of objects from a user-defined RecordSet.  " & _
  3446.             "Object count=" & pvtCollection.Count
  3447.     End If
  3448. #End If
  3449.  
  3450. ' trigger the "PopulatedFromRecordSet" event for Me
  3451. #If NoEventMgr = False Then
  3452.     TriggerCollectionEvent _
  3453.         Event:="PopulatedFromRecordSet"
  3454. #End If
  3455.     
  3456.     Set pvtPopulateFromRecordSet = Me
  3457. End Function
  3458.  
  3459. Public Property Get RecordSet() As RecordSet
  3460. Attribute RecordSet.VB_Description = "Returns the underlying RecordSet object"
  3461. ' Returns a DataControl-ready RecordSet object
  3462. '   which pertains to the collection of objects
  3463. '   instantiated and contained within this
  3464. '   VBOFCollection
  3465.     
  3466.     If pvtCollectionEmulationMode Then
  3467.         Set RecordSet = Nothing
  3468.         Exit Property
  3469.     End If
  3470.     
  3471.     Set RecordSet = pvtRecordSet
  3472. End Property
  3473.  
  3474. Public Function Sort( _
  3475.     Optional SortField As Variant, _
  3476.     Optional SortOrder As Variant) As Boolean
  3477. ' Sort the objects within this collection.
  3478. ' The ObjectSortCompare method of each object is
  3479. '   invoked to perform a comparison of itself with
  3480. '   another object provided by this method.
  3481. '   The object's ObjectSortCompare method must return
  3482. '   one of the following values, indicating its sort
  3483. '   status, relative to the other object:
  3484. '       -1 object has a lower valued field than the
  3485. '          other object
  3486. '       0  object has the same valued field as the
  3487. '          other object
  3488. '       1  object has a higher valued field than the
  3489. '          other object
  3490. '
  3491. ' Note: the application objects can use the method
  3492. '   ObjectManager.CompareSortOrder for assistance
  3493. ' Note: the objects in the collection must have the
  3494. '   ObjectSortCompare method
  3495. '
  3496. ' Programming example
  3497. '   MyVBOFCollection.Sort _
  3498. '       SortField:=FormattedName, _
  3499. '       SortOrder:="ASC"
  3500.     
  3501.     Dim tempObject As Variant
  3502.     Dim tempCompareObject As Variant
  3503.     Dim tempCompareResults As Long
  3504.     Dim I As Long
  3505.     Dim J As Long
  3506.     
  3507. ' bullet-proofing
  3508.     If IsMissing(SortField) Then
  3509.         pvtErrorMessage TypeName(Me) & " cannot process the '.Sort' method because the 'SortField:=' parameter is missing."
  3510.         Exit Function
  3511.     End If
  3512.     If IsMissing(SortOrder) Then
  3513.         pvtErrorMessage TypeName(Me) & " cannot process the '.Sort' method because the 'SortOrder:=' parameter is missing."
  3514.         Exit Function
  3515.     End If
  3516.  
  3517. ' sort the objects
  3518.     For I = 1 To Me.Collection.Count - 1
  3519.         For J = I + 1 To Me.Collection.Count
  3520.             Set tempObject = _
  3521.                 Me.Collection.Item(CLng(I))
  3522.             Set tempCompareObject = _
  3523.                 Me.Collection.Item(CLng(J))
  3524.             
  3525. ' have the I object compare itself to the J object
  3526.             tempCompareResults = _
  3527.                 tempObject.ObjectSortCompare( _
  3528.                     SortField:=SortField, _
  3529.                     SortOrder:=SortOrder, _
  3530.                     CompareObject:=tempCompareObject)
  3531.     
  3532. ' swap the objects in the collection
  3533.             If tempCompareResults > 0 _
  3534.             Or (tempCompareResults = 0 _
  3535.                 And pvtSwapIfEqualSortOrder) _
  3536.             Then
  3537.                 pvtCollection.Remove I
  3538.                 pvtCollection.Add _
  3539.                     Item:=tempObject, _
  3540.                     After:=CLng(J - 1)
  3541.  
  3542.                 pvtCollection.Remove J - 1
  3543.                 If I > 1 Then
  3544.                     pvtCollection.Add _
  3545.                         Item:=tempCompareObject, _
  3546.                         After:=CLng(I - 1)
  3547.                 Else
  3548.                     pvtCollection.Add _
  3549.                         Item:=tempCompareObject, _
  3550.                         Before:=1
  3551.                 End If
  3552.     
  3553.                 pvtDBGridBookmarkArraySwap I - 1, J - 1
  3554.             End If
  3555.         Next J
  3556.     Next I
  3557.  
  3558. End Function
  3559.  
  3560. Public Property Get SQLStatement() As String
  3561. Attribute SQLStatement.VB_Description = "Returns the most recently used SQL statement"
  3562. ' Returns the SQL statement used to retrieve data
  3563. '   rows from the specified Sample.ObjectDataSource
  3564. '   to be used to create the current set of objects
  3565.     SQLStatement = pvtSQLStatement
  3566. End Property
  3567.  
  3568. Public Function Refresh() As VBOFCollection
  3569. Attribute Refresh.VB_Description = "Refreshes the internally managed RecordSet which equates to the rows of the table which were used to instantiate the contained items.  Returns the refreshed VBOFCollection"
  3570. ' Return a refreshed VBOFCollection, using again
  3571. '   the same SQL-oriented information used previously
  3572. '   to generate the current VBOFCollection state.
  3573. ' Note: users of the method "pvtPopulateFromRecordSet"
  3574. '   should not use this method
  3575.  
  3576.     On Local Error Resume Next
  3577.  
  3578. ' bullet-proofing
  3579.     If pvtRecordSetProvidedByUser Then
  3580.         pvtErrorMessage TypeName(Me) & " cannot process the '.Refresh' method because the RecordSet used to instantiate the objects was provided by the user via the '.pvtPopulateFromRecordSet' method."
  3581.         Set Refresh = Me
  3582.         GoTo Refresh_Exit
  3583.     End If
  3584.  
  3585. ' refresh the Collection
  3586.     If pvtCollectionEmulationMode Then
  3587.         Set Refresh = Me
  3588.     Else
  3589.         Set Refresh = _
  3590.             pvtPopulateFromDatabase()
  3591.     End If
  3592.     
  3593. #If NoDebugMode = False Then
  3594.     If pvtVBOFObjectManager.DebugMode Then
  3595.         pvtVBOFObjectManager.DisplayDebugMessage _
  3596.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has refreshed its collection of objects (.Refresh).  " & _
  3597.             "Object count=" & pvtCollection.Count
  3598.     End If
  3599. #End If
  3600.  
  3601. Refresh_Exit:
  3602. ' trigger the "Refreshed" event for Me
  3603. #If NoEventMgr = False Then
  3604.     TriggerCollectionEvent _
  3605.         Event:="Refreshed"
  3606. #End If
  3607.  
  3608.     Exit Function
  3609. End Function
  3610.  
  3611. Public Function Remove( _
  3612.     Optional Item As Variant, _
  3613.     Optional Object As Variant, _
  3614.     Optional ObjectID As Variant, _
  3615.     Optional Key As Variant, _
  3616.     Optional NoDelete As Variant, _
  3617.     Optional NoRefresh As Variant, _
  3618.     Optional CleanUpMode As Variant, _
  3619.     Optional CollectionEventNoDelete As Variant) As VBOFCollection
  3620. ' Remove the Item from the VBOFCollection and
  3621. '   return the VBOFCollection
  3622. ' Note: if a Table is supporting the Collection,
  3623. '   then the VBOF automatic containment link to
  3624. '   the contained object (Me.Parent) is also severed
  3625. '   (unless CleanUpMode:=True).
  3626. '   See also, the method "pvtEmptyCollection"
  3627.  
  3628.     Dim tempCountOfParentLinksToItem As Long
  3629.     Dim tempSuppressDelete As Boolean
  3630.     Dim tempPvtDeleteExecuted As Boolean
  3631.     Dim tempCleanUpMode As Boolean
  3632.     Dim tempNoRefresh As Boolean
  3633.     Dim tempCollectionEventNoDelete As Boolean
  3634.     Dim tempSpecifiedParameterObject As Variant
  3635.     Dim tempParameterObjectWasSpecified As Boolean
  3636.  
  3637.     On Local Error Resume Next
  3638.  
  3639. ' bullet-proofing
  3640.     tempParameterObjectWasSpecified = _
  3641.         ObjectManager.pvtChooseObjectFromParameters( _
  3642.             Item:=Item, _
  3643.             Object:=Object, _
  3644.             ReturnObject:=tempSpecifiedParameterObject)
  3645.     If Not tempParameterObjectWasSpecified _
  3646.     Or tempSpecifiedParameterObject Is Nothing _
  3647.     Then
  3648.         Remove = Me
  3649.         Exit Function
  3650.     End If
  3651.     tempSuppressDelete = False
  3652.     If Not IsMissing(NoDelete) Then
  3653.         tempSuppressDelete = NoDelete
  3654.     End If
  3655.     tempCleanUpMode = False
  3656.     If Not IsMissing(CleanUpMode) Then
  3657.         tempCleanUpMode = CleanUpMode
  3658.     End If
  3659.     tempNoRefresh = False
  3660.     If Not IsMissing(NoRefresh) Then
  3661.         tempNoRefresh = NoRefresh
  3662.     End If
  3663.     tempCollectionEventNoDelete = False
  3664.     If Not IsMissing(CollectionEventNoDelete) Then
  3665.         tempCollectionEventNoDelete = CollectionEventNoDelete
  3666.     End If
  3667.  
  3668. ' sever the link from pvtParent to Item
  3669.     If Not pvtCollectionEmulationMode _
  3670.     And Not tempSuppressDelete Then
  3671.         pvtDeleteParentLinksToItem _
  3672.             Child:=tempSpecifiedParameterObject, _
  3673.             Parent:=pvtParent
  3674.     End If
  3675.  
  3676. ' remove the reference from the
  3677. '   pvtDBGridBookmarkArray
  3678.     pvtDBGridBookmarkArrayDeleteRowIndex ( _
  3679.         pvtDBGridRowIndexAtObjectID _
  3680.             (CStr(tempSpecifiedParameterObject.ObjectID)))
  3681.         
  3682. ' remove Item from the Collection
  3683.     pvtCollection.Remove _
  3684.         CollectionIndex(tempSpecifiedParameterObject)
  3685.  
  3686. ' trigger the "RemovedItem" event to other Collections
  3687. #If NoEventMgr = False Then
  3688.     If Not CleanUpMode Then
  3689.         TriggerCollectionEvent _
  3690.             Object:=tempSpecifiedParameterObject, _
  3691.             Event:="RemovedItem", _
  3692.             NoDelete:=tempCollectionEventNoDelete
  3693.     End If
  3694. #End If
  3695.     
  3696. ' if not operating in Collection-emulation mode
  3697.     If Not pvtCollectionEmulationMode _
  3698.     And Not tempCleanUpMode _
  3699.     Then
  3700.  
  3701. ' check for orphan and other conditions necessary before
  3702. '   actually removing an Item from the database
  3703. '   (if not operating in NoDelete mode,
  3704. '   and if the AutoDeleteOrphans option is enabled,
  3705. '   and if the Item actually appears in the
  3706. '   RecordSet)
  3707.         If Not tempSuppressDelete _
  3708.         And Me.AutoDeleteOrphans _
  3709.         And Not pvtPositionRecordSetToItem _
  3710.                 (Item:=tempSpecifiedParameterObject) Is Nothing _
  3711.         And pvtIsAnOrphan _
  3712.                 (Item:=tempSpecifiedParameterObject) _
  3713.         Then
  3714.  
  3715. ' delete Item from the database
  3716. '   and free the Item
  3717.             pvtDBDelete
  3718.         
  3719. ' trigger the "RemovedItem" event for the new object
  3720. '   to any other listeners
  3721. #If NoEventMgr = False Then
  3722.             If Not CleanUpMode Then
  3723.                 TriggerObjectEvent _
  3724.                     Object:=tempSpecifiedParameterObject, _
  3725.                     Event:="RemovedItem"
  3726.             End If
  3727. #End If
  3728.  
  3729. ' else, just Refresh the current RecordSet to
  3730. '   reflect the detached Item
  3731.         ElseIf Not pvtRecordSetProvidedByUser _
  3732.         And Not tempNoRefresh _
  3733.         Then
  3734.             Refresh
  3735.         End If
  3736.     End If
  3737.     
  3738. #If NoDebugMode = False Then
  3739.     If pvtVBOFObjectManager.DebugMode Then
  3740.         pvtVBOFObjectManager.DisplayDebugMessage _
  3741.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has removed an object from the collection.  ObjectType=" & _
  3742.             TypeName(tempSpecifiedParameterObject) & _
  3743.             ", ObjectID=" & _
  3744.             tempSpecifiedParameterObject.ObjectID
  3745.     End If
  3746. #End If
  3747.  
  3748.     Set Remove = Me
  3749. End Function
  3750.  
  3751. Private Function pvtCountOfParentLinksToItem(Optional Parent As Variant, Optional Child As Variant) As Long
  3752. ' Return the number of Parent links exist for
  3753. '   the specified Child object
  3754.  
  3755.     Dim SQLStatement As String
  3756.     Dim tempRecordSet As RecordSet
  3757.  
  3758.     On Local Error Resume Next
  3759.  
  3760. ' bullet-proofing
  3761.     If IsMissing(Parent) _
  3762.     Or IsMissing(Child) _
  3763.     Or pvtCollectionEmulationMode Then
  3764.         pvtCountOfParentLinksToItem = -1
  3765.         Exit Function
  3766.     End If
  3767.     
  3768.     Err = 0
  3769.  
  3770. ' build the SQL statement to perform the Count
  3771.     SQLStatement = _
  3772.         "SELECT COUNT(*) FROM " & ObjectDataSource() & " " & _
  3773.         "WHERE ToObjectType = '" & _
  3774.         TypeName(Child) & "' AND ToObjectID = " & _
  3775.         Child.ObjectID
  3776.         
  3777. ' check for non-existent Object
  3778.     If Err = 91 Then
  3779.         pvtCountOfParentLinksToItem = 0
  3780.         Exit Function
  3781.     End If
  3782.     
  3783.     Set tempRecordSet = _
  3784.         pvtDatabase. _
  3785.             OpenRecordset( _
  3786.                 SQLStatement, _
  3787.                 dbOpenDynaset + pvtODBCPassThrough)
  3788.  
  3789.     If Err <> 0 And Err <> 91 Then
  3790.         pvtErrorMessage _
  3791.             TypeName(Me) & " received a database error while attempting to count the object containment links (Select Count(*))."
  3792.         pvtCountOfParentLinksToItem = 0
  3793.     Else
  3794.         pvtCountOfParentLinksToItem = _
  3795.             tempRecordSet(0)
  3796.     End If
  3797.  
  3798.     Set tempRecordSet = Nothing
  3799. End Function
  3800.  
  3801. Private Function pvtDeleteParentLinksToItem(Optional Parent As Variant, Optional Child As Variant) As Long
  3802. ' Remove the link between the Parent and Child
  3803.     
  3804.     Dim SQLStatement As String
  3805.     
  3806.     On Local Error Resume Next
  3807.  
  3808.     If pvtCollectionEmulationMode Then
  3809.         pvtDeleteParentLinksToItem = True
  3810.         Exit Function
  3811.     End If
  3812.     
  3813.     Err = 0
  3814.  
  3815. ' delete the row from the VBObjectFrameworkObjectLinks table
  3816.     SQLStatement = _
  3817.         "DELETE FROM " & ObjectDataSource() & " WHERE FromObjectType = '" & _
  3818.         TypeName(Parent) & "' AND FromObjectID = " & _
  3819.         Parent.ObjectID & " AND ToObjectType = '" & _
  3820.         TypeName(Child) & "' AND ToObjectID = " & _
  3821.         Child.ObjectID
  3822.     
  3823. ' check for illegal Object
  3824.     If Err = 91 Then
  3825.         pvtDeleteParentLinksToItem = False
  3826.         Exit Function
  3827.     End If
  3828.     
  3829.     pvtDatabase.Execute SQLStatement, pvtODBCPassThrough
  3830.     If Err <> 0 And Err <> 3078 And Err <> 91 Then
  3831.         pvtErrorMessage TypeName(Me) & " received a database error while attempting to remove an object containment link (Delete)."
  3832.         pvtDeleteParentLinksToItem = False
  3833.         Exit Function
  3834.     End If
  3835.         
  3836.     pvtDeleteParentLinksToItem = True
  3837. End Function
  3838.  
  3839. Public Function Replace( _
  3840.     Optional Item As Variant, _
  3841.     Optional Object As Variant, _
  3842.     Optional ObjectID As Variant, _
  3843.     Optional ReplaceWith As Variant) As VBOFCollection
  3844. ' Replace the specified Item with the ReplaceWith
  3845. '   Item, then return the VBOFCollection
  3846.     
  3847.     Dim ItemIndex As Long
  3848.     Dim tempSpecifiedParameterObject As Variant
  3849.     Dim tempParameterObjectWasSpecified As Boolean
  3850.     
  3851.     On Local Error Resume Next
  3852.  
  3853. ' bullet-proofing
  3854.     tempParameterObjectWasSpecified = _
  3855.         ObjectManager.pvtChooseObjectFromParameters( _
  3856.             Item:=Item, _
  3857.             Object:=Object, _
  3858.             ReturnObject:=tempSpecifiedParameterObject)
  3859.     If Not tempParameterObjectWasSpecified _
  3860.     Or tempSpecifiedParameterObject Is Nothing _
  3861.     Or IsMissing(ReplaceWith) Then
  3862.         Set Replace = Me
  3863.         GoTo Replace_Exit
  3864.     End If
  3865.     
  3866. ' there are two ways to handle a Replace:
  3867. '   1) replace the object in-place
  3868. '       (non Collection-emulation mode, only),
  3869. '   2) replace the object with another
  3870. '
  3871. ' process the replacement in-place:
  3872.     If tempSpecifiedParameterObject.ObjectID = _
  3873.         ReplaceWith.ObjectID _
  3874.     And Not pvtCollectionEmulationMode Then
  3875.         
  3876. ' position to the correct record in the RecordSet.
  3877. '   Note:  with non-DataControl uses of VBOFCollection,
  3878. '   it is possible for the correlation to be lost
  3879. '   between the current record of the RecordSet and
  3880. '   the user-selected object.
  3881. ' position the RecordSet to the Item
  3882.         If pvtPositionRecordSetToItem( _
  3883.             Item:=tempSpecifiedParameterObject) _
  3884.             Is Nothing _
  3885.         Then
  3886.             Set Replace = Me
  3887.             GoTo Replace_Exit
  3888.         End If
  3889.         
  3890. ' initiate the RecordSet.Edit
  3891.         pvtRecordSet.Edit
  3892.         
  3893. ' have ReplaceWith initialize the RecordSet
  3894.         ReplaceWith. _
  3895.             ObjectInitializeRecordSet _
  3896.                 pvtRecordSet
  3897.         If Err = pvtReceiverDoesNotSupportThisMethod Then
  3898.             pvtErrorMessage "Class Module '" & TypeName(ReplaceWith) & "' does not support the method 'InitializeRecordSet'." & vbCrLf & "Object cannot be supported by " & TypeName(Me) & " without this method."
  3899.         End If
  3900.         
  3901. ' post the updates to the database
  3902.         pvtRecordSet.Update
  3903.         
  3904. ' execute Me.Refresh
  3905.         Refresh
  3906.         
  3907.         Set Replace = Me
  3908.         GoTo Replace_Exit
  3909.     End If
  3910.     
  3911. ' else, Item must be removed and replaced with ReplaceWith.
  3912. ' save the position of Item in the Collection
  3913.     ItemIndex = _
  3914.         CollectionIndex _
  3915.             (tempSpecifiedParameterObject)
  3916.  
  3917. ' remove Item from the RecordSet and the Collection
  3918.     Remove _
  3919.         Item:=tempSpecifiedParameterObject, _
  3920.         Key:=CStr(tempSpecifiedParameterObject.ObjectID), _
  3921.         NoDelete:=False, _
  3922.         CollectionEventNoDelete:=True
  3923.  
  3924. ' add the ReplaceWith item
  3925.     If ItemIndex > 0 Then
  3926.         Add _
  3927.             Item:=ReplaceWith, _
  3928.             Parent:=pvtParent, _
  3929.             After:=(ItemIndex - 1)
  3930.     Else
  3931.         Add _
  3932.             Item:=ReplaceWith, _
  3933.             Parent:=pvtParent
  3934.     End If
  3935.     
  3936. #If NoDebugMode = False Then
  3937.     If pvtVBOFObjectManager.DebugMode Then
  3938.         pvtVBOFObjectManager.DisplayDebugMessage _
  3939.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has replaces an object in the collection.  Original ObjectType=" & _
  3940.             TypeName(tempSpecifiedParameterObject) & _
  3941.             ", ObjectID=" & _
  3942.             tempSpecifiedParameterObject.ObjectID & " replaced with ObjectType=" & _
  3943.             TypeName(ReplaceWith) & _
  3944.             ", ObjectID=" & _
  3945.             ReplaceWith.ObjectID
  3946.     End If
  3947. #End If
  3948.  
  3949. Replace_Exit:
  3950. ' trigger the "Replaced" event for Me
  3951. #If NoEventMgr = False Then
  3952.     TriggerCollectionEvent _
  3953.         Object:=tempSpecifiedParameterObject, _
  3954.         Event:="ReplacedItem"
  3955. #End If
  3956.  
  3957. ' free Item
  3958.     Set tempSpecifiedParameterObject = Nothing
  3959.  
  3960.     Set Replace = Me
  3961. End Function
  3962.  
  3963. Public Function Commit() As Long
  3964. Attribute Commit.VB_Description = "Private"
  3965. ' Commit each Object in the collection
  3966. ' Note: although this method is Public, it
  3967. '   should not be executed by any object
  3968. '   other than the governing
  3969. '   VBOFObjectManager
  3970.  
  3971. '>>
  3972. MsgBox "This function, Commit, is under construction. Please do not use it yet.", 0, "VBOF Feature Unavailable"
  3973. Exit Function
  3974.  
  3975.     Dim tempObject As Object
  3976.     
  3977.     On Local Error Resume Next
  3978.     
  3979. #If NoDebugMode = False Then
  3980.     If pvtVBOFObjectManager.DebugMode Then
  3981.         pvtVBOFObjectManager.DisplayDebugMessage _
  3982.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has begun 'Commit' processing"
  3983.     End If
  3984. #End If
  3985.  
  3986. ' process each object
  3987.     For Each tempObject In pvtCollection
  3988.     
  3989. ' position the RecordSet to correspond to the
  3990. '   current object
  3991.         pvtRecordSet.FindFirst _
  3992.             "ObjectID = " & _
  3993.             tempObject.ObjectID
  3994.             
  3995.         If Err = 0 Then
  3996.             pvtRecordSet.Edit
  3997.             
  3998. ' allow the object to populate the RecordSet
  3999.             tempObject. _
  4000.                 ObjectInitializeRecordSet _
  4001.                     RecordSet:=pvtRecordSet
  4002.         
  4003.             pvtRecordSet.Update
  4004.         End If
  4005.         
  4006.     Next tempObject
  4007.     
  4008. #If NoDebugMode = False Then
  4009.     If pvtVBOFObjectManager.DebugMode Then
  4010.         pvtVBOFObjectManager.DisplayDebugMessage _
  4011.             TypeName(Me) & ", ObjectID=" & Me.ObjectID & ", has completed 'Commit' processing"
  4012.     End If
  4013. #End If
  4014.  
  4015. ' trigger the "Committed" event for the new object
  4016. #If NoEventMgr = False Then
  4017.     TriggerCollectionEvent _
  4018.         Event:="Committed"
  4019. #End If
  4020.  
  4021.     Set tempObject = Nothing
  4022. End Function
  4023. Private Function pvtPositionRecordSetToItem(Optional Item As Variant) As Variant
  4024. Attribute pvtPositionRecordSetToItem.VB_Description = "(Private) internal function"
  4025. ' Position to the RecordSet row which equates to
  4026. '   the specified Item
  4027.  
  4028.     Dim I As Long
  4029.     Dim tempItemFound As Boolean
  4030.     
  4031.     On Local Error Resume Next
  4032.     Err = 0
  4033.     
  4034. ' check the current record first
  4035. '   (performance feature)
  4036.     If Not pvtRecordSet.BOF _
  4037.     And Not pvtRecordSet.EOF _
  4038.     And pvtRecordSet.RecordCount > 0 Then
  4039.         If pvtRecordSet("ObjectID") = CStr(Item.ObjectID) Then
  4040.             Set pvtPositionRecordSetToItem = Item
  4041.             Exit Function
  4042.         End If
  4043.     End If
  4044.     
  4045. ' else, .FindFirst
  4046. '    pvtRecordSet.MoveFirst
  4047.     pvtRecordSet.FindFirst _
  4048.         "ObjectID = " & CStr(Item.ObjectID)
  4049.     
  4050. ' Caution: the application's responses to the
  4051. '   RecordSet might distort the following
  4052. '   processing
  4053.     tempItemFound = _
  4054.         Not pvtRecordSet.NoMatch
  4055.     
  4056. ' This is potentially a very dangerous area (see
  4057. '   preceeding comment).  Make one final check
  4058. '   before returning True
  4059.     If Not tempItemFound _
  4060.     Or pvtRecordSet("ObjectID") <> CStr(Item.ObjectID) Then
  4061.         Set pvtPositionRecordSetToItem = Nothing
  4062.     Else
  4063.         Set pvtPositionRecordSetToItem = Item
  4064.     End If
  4065. End Function
  4066.  
  4067. Public Property Get SwapIfEqualSortOrder() As Boolean
  4068.     SwapIfEqualSortOrder = pvtSwapIfEqualSortOrder
  4069. End Property
  4070.  
  4071. Public Property Let SwapIfEqualSortOrder(aBoolean As Boolean)
  4072.     pvtSwapIfEqualSortOrder = aBoolean
  4073. End Property
  4074.  
  4075.  
  4076.  
  4077. Private Function TriggerObjectEvent( _
  4078.     Optional Object As Variant, _
  4079.     Optional Event As Variant) As Boolean
  4080. ' Pass-through to ObjectManager
  4081.     
  4082. #If NoEventMgr = False Then
  4083.     pvtVBOFObjectManager. _
  4084.         TriggerObjectEvent _
  4085.             Event:=Event, _
  4086.             Object:=Object
  4087. #End If
  4088.  
  4089. End Function
  4090.  
  4091. Private Function TriggerCollectionEvent( _
  4092.     Optional Object As Variant, _
  4093.     Optional Event As Variant, _
  4094.     Optional NoDelete As Variant) As Boolean
  4095. ' Pass-through to ObjectManager
  4096.     
  4097. #If NoEventMgr = False Then
  4098.     pvtVBOFObjectManager. _
  4099.         TriggerCollectionEvent _
  4100.             Event:=Event, _
  4101.             Object:=Object, _
  4102.             Collection:=Me, _
  4103.             NoDelete:=NoDelete
  4104. #End If
  4105.  
  4106. End Function
  4107.  
  4108.  
  4109. Private Sub Class_Initialize()
  4110. Attribute Class_Initialize.VB_Description = "Private"
  4111.  
  4112.     Set pvtCollection = New Collection
  4113.     Set pvtSample = Nothing
  4114.     Set pvtParent = Nothing
  4115.     Set pvtDatabase = Nothing
  4116.     Set pvtRecordSet = Nothing
  4117.     Set pvtVBOFObjectManager = Nothing
  4118.     Set pvtMostRecentlyAddedObject = Nothing
  4119.     Set pvtVBOFListBoxWrapper = Nothing
  4120.     Set pvtListBox = Nothing
  4121.     
  4122.     pvtANSISQL = False
  4123.     pvtODBCPassThrough = 0
  4124.     pvtSQLStatement = ""
  4125.     pvtWhereClause = ""
  4126.     pvtDBHasBeenReferenced = False
  4127.     pvtCollectionEmulationMode = True
  4128.     pvtRecordSetProvidedByUser = False
  4129.     pvtSQLStatementProvidedByUser = False
  4130.     pvtDBGridBookmarkArrayAvailable = False
  4131.     pvtAutoDeleteOrphansHasBeenInitialized = False
  4132.     
  4133.     ObjectID = -1
  4134. End Sub
  4135. Public Property Get WhereClause() As String
  4136. Attribute WhereClause.VB_Description = "Sets the WhereClause property"
  4137. ' Returns the current WhereClause value
  4138.     
  4139.     WhereClause = pvtWhereClause
  4140. End Property
  4141.  
  4142. Public Property Let WhereClause(WhereClause As String)
  4143. ' Set the WhereClause to be used in future SQL
  4144. '   Select statements
  4145. ' Note: this step is not necessarily required of
  4146. '   the application
  4147.  
  4148.     pvtReceiveGeneralParameters _
  4149.         WhereClause:=WhereClause
  4150.         
  4151.     pvtCollectionEmulationMode = False
  4152. End Property
  4153.  
  4154. Public Property Get OrderByClause() As String
  4155. Attribute OrderByClause.VB_Description = "Sets the OrderByClause property"
  4156. ' Returns the current OrderByClause
  4157.     
  4158.     OrderByClause = pvtOrderByClause
  4159. End Property
  4160.  
  4161. Public Property Let OrderByClause(OrderByClause As String)
  4162. ' Set the OrderByClause to be used in future SQL Select
  4163. '   statements
  4164. ' Note: this step is not necessarily required of the user
  4165.  
  4166.     pvtReceiveGeneralParameters _
  4167.         OrderByClause:=OrderByClause
  4168.             
  4169.     pvtCollectionEmulationMode = False
  4170. End Property
  4171.  
  4172. Public Property Get Owner() As Variant
  4173. ' Return my owner
  4174.     
  4175. MsgBox "Shouldn't be using 'Owner'.  Use 'Parent' instead."
  4176. '    On Local Error Resume Next
  4177. '
  4178. '    If pvtOwner Is Nothing Or Err = 424 Then
  4179. '        Set Owner = Nothing
  4180. '    Else
  4181. '        Set Owner = pvtOwner
  4182. '    End If
  4183. End Property
  4184.  
  4185. Public Property Set Parent(anObject As Variant)
  4186.     Set pvtParent = anObject
  4187. End Property
  4188.  
  4189. Private Sub Class_Terminate()
  4190. Attribute Class_Terminate.VB_Description = "Private"
  4191.     
  4192.     On Local Error Resume Next
  4193.  
  4194.     pvtCloseRecordSet
  4195.  
  4196. #If NoEventMgr = False Then
  4197.     pvtVBOFObjectManager. _
  4198.         UnRegisterForAllEvents _
  4199.         RegisterObject:=Me
  4200. #End If
  4201.  
  4202.     If Not pvtVBOFObjectManager Is Nothing Then
  4203.         pvtVBOFObjectManager.EmptyCollection _
  4204.             Collection:=Me, _
  4205.             CleanUpMode:=True
  4206.     End If
  4207.  
  4208. End Sub
  4209.  
  4210.  
  4211.  
  4212.  
  4213. Public Function ObjectEventCallBack(Optional Event As Variant, Optional Object As Variant, Optional NoDelete As Variant) As Long
  4214. Attribute ObjectEventCallBack.VB_Description = "Private"
  4215. ' This method is typically invoked when another
  4216. '   VBOFCollection is changing an
  4217. '   item in itself
  4218.  
  4219.     Dim tempObject As Object
  4220.     Dim tempUCaseEvent As String
  4221.     Dim tempNoDelete As Boolean
  4222.     
  4223.     tempUCaseEvent = UCase$(Event)
  4224.     
  4225. ' (performance feature)
  4226. ' check for empty Collection
  4227.     If pvtCollection.Count = 0 Then
  4228.         Exit Function
  4229.     End If
  4230.     
  4231. ' (performance feature)
  4232. ' check the TriggerObject's first object's type
  4233. '   against my first object's type
  4234.     If TypeName(Object) <> _
  4235.         TypeName(pvtCollection.Item(1)) _
  4236.     Then
  4237.         Exit Function
  4238.     End If
  4239.     
  4240.     tempNoDelete = False
  4241.     If Not IsMissing(NoDelete) Then
  4242.         tempNoDelete = NoDelete
  4243.     End If
  4244.     
  4245. ' scan the objects contained herein,
  4246. '   look for the item about which the trigger
  4247. '   is associated
  4248.     For Each tempObject In pvtCollection
  4249.     
  4250.         If tempObject.ObjectID = Object.ObjectID Then
  4251.             
  4252.             If tempUCaseEvent = "REMOVEDITEM" _
  4253.             And Not tempNoDelete Then
  4254.                 pvtCollection.Remove _
  4255.                     CollectionIndex(Item:=tempObject)
  4256.                 
  4257. ' tell any Object Event listeners of the change to
  4258. '   the Collection
  4259. '   (like a GUI, for example)
  4260.                 TriggerObjectEvent _
  4261.                     Object:=Object, _
  4262.                     Event:=Event
  4263.             End If
  4264.              
  4265.             If tempUCaseEvent = "REPLACEDITEM" Then
  4266.                 
  4267. ' tell any Object Event listeners of the change to
  4268. '   the Collection
  4269. '   (like a GUI, for example)
  4270.                 TriggerObjectEvent _
  4271.                     Object:=Object, _
  4272.                     Event:=Event
  4273.             End If
  4274.        End If
  4275.             
  4276.     Next tempObject
  4277.  
  4278.     Set tempObject = Nothing
  4279. End Function
  4280.